Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion deploy/cloudflare/src/steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ export async function discoverModules(rootDir: string, selectedIds: string[]): P
return refs;
}

/** 多级子域判定:Universal SSL 只覆盖 apex + 一级通配(*.zone),更深的需要 Total TLS。 */
export function needsTotalTls(domain: string, zoneName: string): boolean {
return domain.split('.').length > zoneName.split('.').length + 1;
}

/** 九步主流程。返回部署摘要(供测试断言与部署输出)。 */
export async function runNineSteps(input: {
rootDir: string;
Expand Down Expand Up @@ -181,8 +186,14 @@ export async function runNineSteps(input: {
await removeLegacyCustomDomains({ accountId, domain: config.domain, apiToken: token, log: rep.log });
});
await cleanup();
// 多级子域不在 Universal SSL 覆盖内:提前触发 Total TLS 签发(幂等)
// 多级子域不在 Universal SSL 覆盖内:提前触发 Total TLS 签发(幂等)。
// 一级子域(*.zone)由 Universal SSL 通配证书覆盖,无需 Total TLS(且免费计划无 ACM 会报 1450)
const needsTls = needsTotalTls(config.domain, zone.name);
const totalTls = input.ensureTotalTls ?? (async () => {
if (!needsTls) {
rep.log(`跳过 Total TLS:${config.domain} 为一级子域(Universal SSL 覆盖)`);
return;
}
await ensureTotalTls({
zoneId: zone.id,
apiToken: process.env.CLOUDFLARE_API_TOKEN ?? '',
Expand Down
14 changes: 13 additions & 1 deletion deploy/cloudflare/test/steps.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-only
import { describe, expect, it } from 'vitest';
import { runNineSteps } from '../src/steps';
import { needsTotalTls, runNineSteps } from '../src/steps';
import type { Wrangler } from '../src/wrangler';

/**
Expand Down Expand Up @@ -100,6 +100,18 @@ const SMOKE_OK = {
),
};

describe('needsTotalTls(Universal SSL 覆盖边界)', () => {
it('一级子域:覆盖,不需要', () => {
expect(needsTotalTls('unself.handywote.top', 'handywote.top')).toBe(false);
});
it('多级子域:不覆盖,需要', () => {
expect(needsTotalTls('unself.demo.handywote.top', 'handywote.top')).toBe(true);
});
it('apex 自身:覆盖,不需要', () => {
expect(needsTotalTls('handywote.top', 'handywote.top')).toBe(false);
});
});

describe('runNineSteps(九步编排 · 幂等收敛)', () => {
it('空账号首跑:命令序列覆盖九步;二跑零 create/put(收敛)', { timeout: 120_000 }, async () => {
const first = makeFakeWrangler();
Expand Down
Loading