import assert from 'node:assert/strict' import { readFile } from 'node:fs/promises' import test from 'node:test' const workflowUrl = new URL('../../../.github/workflows/dsh-upstream-update.yml', import.meta.url) const validationUrl = new URL('../../../.github/workflows/dsh-candidate-validation.yml', import.meta.url) const productionUrl = new URL('../../../.github/workflows/production-publish.yml', import.meta.url) const notificationsUrl = new URL('../../../.github/workflows/workflow-notifications.yml', import.meta.url) const dockerUrl = new URL('../../../.github/workflows/docker.yaml', import.meta.url) const gotifyWorkflow = 'yjrszcq/github-workflows/.github/workflows/gotify-notify.yml@c4c7fe9e17854cd4962913ac2792513eab0be988' test('upstream workflow discovers candidates without production credentials', async () => { const workflow = await readFile(workflowUrl, 'utf8') assert.match(workflow, /schedule:/) assert.match(workflow, /workflow_dispatch:/) assert.match(workflow, /contents: write/) assert.match(workflow, /pull-requests: write/) assert.match(workflow, /BASE_BRANCH: dev/) assert.match(workflow, /ref: \$\{\{ env\.BASE_BRANCH \}\}/) assert.match(workflow, /supported-target\.mjs" advance/) assert.match(workflow, /trusted-platform/) assert.match(workflow, /node "\$trusted_platform\/tools\/supported-target\.mjs"/) assert.match(workflow, /jq -r 'if \(\.changed \| type\) == "boolean" then \.changed else error\("expected boolean changed"\) end'/) assert.doesNotMatch(workflow, /jq -er '\.changed'/) assert.match(workflow, /candidate_remote_sha="\$\(git ls-remote --heads origin/) assert.match(workflow, /git switch --create "\$CANDIDATE_BRANCH" "\$base_sha"/) assert.match(workflow, /git push --force-with-lease="refs\/heads\/\$CANDIDATE_BRANCH:\$candidate_remote_sha"/) assert.match(workflow, /git push origin/) assert.match(workflow, /chore\(dsh\): validate/) assert.match(workflow, /gh pr create[\s\S]*--base "\$BASE_BRANCH"/) assert.match(workflow, /gh pr edit "\$pr_number"[\s\S]*--base "\$BASE_BRANCH"/) assert.doesNotMatch(workflow, /github\.event\.repository\.default_branch/) assert.doesNotMatch(workflow, /DSH_RELEASE_PRIVATE_KEY|DSH_RECOVERY|DOCKER_TOKEN/) }) test('upstream workflow calls only the pinned reusable Gotify interface', async () => { const workflow = await readFile(workflowUrl, 'utf8') assert.equal(workflow.split(gotifyWorkflow).length - 1, 2) assert.match(workflow, /gotify_url: \$\{\{ secrets\.GOTIFY_URL \}\}/) assert.match(workflow, /gotify_token: \$\{\{ secrets\.GOTIFY_TOKEN \}\}/) assert.doesNotMatch(workflow, /secrets: inherit/) }) test('candidate validation is secret-free and exercises the complete current Environment', async () => { const workflow = await readFile(validationUrl, 'utf8') assert.match(workflow, /workflow_call:/) assert.match(workflow, /workflow_dispatch:/) assert.match(workflow, /pull_request_target:/) assert.doesNotMatch(workflow, /^ pull_request:/m) assert.match(workflow, /github\.event_name != 'pull_request_target'/) assert.match(workflow, /github\.event\.pull_request\.head\.ref != 'automation\/dsh-upstream-candidate'/) assert.match(workflow, /persist-credentials: false/) assert.match(workflow, /inputs\.ref \|\| github\.event\.pull_request\.head\.sha \|\| github\.sha/) assert.match(workflow, /permissions:\n contents: read/) assert.match(workflow, /supported-target\.mjs validate/) assert.match(workflow, /dist\.integrity/) assert.match(workflow, /npm test --prefix container\/control-plane\/services\/gateway/) assert.match(workflow, /npm test --prefix container\/platform/) assert.match(workflow, /cache: npm/) assert.match(workflow, /cache-dependency-path:[\s\S]*container\/control-plane\/services\/management\/package-lock\.json[\s\S]*container\/environment\/resources\/plugins\/platform-management\/package\/package-lock\.json/) assert.match(workflow, /npm ci --omit=dev --ignore-scripts --no-audit --no-fund --prefix container\/control-plane\/services\/management/) assert.match(workflow, /npm ci --omit=dev --ignore-scripts --no-audit --no-fund --legacy-peer-deps --prefix container\/environment\/resources\/plugins\/platform-management\/package/) assert.match(workflow, /container-smoke\.sh/) assert.match(workflow, /devtools-smoke\.sh/) assert.doesNotMatch(workflow, /secrets\.|DSH_RELEASE_PRIVATE_KEY|DSH_RECOVERY|DOCKER_TOKEN/) }) test('standalone candidate results notify without exposing secrets to candidate code', async () => { const workflow = await readFile(notificationsUrl, 'utf8') assert.match(workflow, /workflow_run:/) assert.match(workflow, /DSH Candidate Validation/) assert.match(workflow, /github\.event\.workflow_run\.event == 'pull_request_target'/) assert.match(workflow, /github\.event\.workflow_run\.event == 'workflow_dispatch'/) assert.match(workflow, /github\.event\.workflow_run\.conclusion == 'success'/) assert.match(workflow, /github\.event\.workflow_run\.conclusion == 'failure'/) assert.match(workflow, /github\.event\.workflow_run\.head_branch != 'automation\/dsh-upstream-candidate'/) assert.match(workflow, /github\.event\.workflow_run\.html_url/) assert.match(workflow, /DSH 候选版本验证通过/) assert.match(workflow, /DSH 候选版本验证失败/) assert.match(workflow, /手动发起的 DSH 候选版本兼容性验证通过/) assert.match(workflow, /手动发起的 DSH 候选版本兼容性验证失败/) assert.doesNotMatch(workflow, /actions\/checkout|\brun:/) }) test('discovery run reports candidate status without duplicate result notifications', async () => { const workflow = await readFile(workflowUrl, 'utf8') assert.match(workflow, /uses: \.\/\.github\/workflows\/dsh-candidate-validation\.yml/) assert.match(workflow, /statuses: write/) assert.match(workflow, /gh pr comment "\$PR_NUMBER" \\\n+\s+--repo "\$GITHUB_REPOSITORY"/) assert.match(workflow, /DSH candidate Runtime/) assert.match(workflow, /notify-discovered:[\s\S]*发现 DSH 上游新版本/) assert.match(workflow, /notify-result:[\s\S]*DSH 上游检查失败/) assert.match(workflow, /候选版本验证通过/) assert.match(workflow, /候选版本验证失败/) assert.doesNotMatch(workflow, /notify-validation-passed:|notify-validation-failed:/) }) test('production publication owns signing, advances an append-only channel, and releases only Environment versions', async () => { const workflow = await readFile(productionUrl, 'utf8') assert.match(workflow, /branches:\n - main/) assert.match(workflow, /release\/supported-target\.json/) assert.match(workflow, /release\/official-dsh-policy\.json/) assert.match(workflow, /environment: production-release/) assert.match(workflow, /if: github\.ref == 'refs\/heads\/main'/) assert.match(workflow, /DSH_RELEASE_PRIVATE_KEY/) assert.match(workflow, /prepare-release\.mjs/) assert.match(workflow, /environment-release\.mjs/) assert.match(workflow, /cache: npm/) assert.match(workflow, /cache-dependency-path:[\s\S]*container\/control-plane\/services\/management\/package-lock\.json[\s\S]*container\/environment\/resources\/plugins\/platform-management\/package\/package-lock\.json/) assert.match(workflow, /npm ci --omit=dev --ignore-scripts --no-audit --no-fund --prefix container\/control-plane\/services\/management/) assert.match(workflow, /npm ci --omit=dev --ignore-scripts --no-audit --no-fund --legacy-peer-deps --prefix container\/environment\/resources\/plugins\/platform-management\/package/) assert.match(workflow, /refs\/heads\/release-channel/) assert.match(workflow, /sequence=1/) assert.match(workflow, /current_sequence \+ 1/) assert.match(workflow, /previous="\$channel\/targets\/\$current_sequence"/) assert.match(workflow, /test -d "\$previous"/) assert.match(workflow, /test -f "\$previous\/\$name"/) assert.match(workflow, /cmp "\$channel\/\$name" "\$previous\/\$name"/) assert.match(workflow, /release-channel\/targets\/\$\{TARGET_SEQUENCE\}/) assert.match(workflow, /test ! -e "\$target"/) assert.match(workflow, /tag="v\$\{ENVIRONMENT_VERSION\}"/) assert.match(workflow, /--title "\$ENVIRONMENT_TAG"/) assert.doesNotMatch(workflow, /--title "DSH Docker Environment/) assert.match(workflow, /cmp "\$RUNNER_TEMP\/environment-release\.json"/) assert.match(workflow, /--draft/) assert.match(workflow, /--draft=false/) assert.match(workflow, /--latest/) assert.match(workflow, /--json isDraft/) assert.match(workflow, /cp "\$RUNNER_TEMP\/environment-release\.json" "\$assets\/"/) assert.match(workflow, /prune_environment_assets\(\)/) assert.match(workflow, /gh release delete-asset "\$ENVIRONMENT_TAG" "\$name" --yes/) assert.match(workflow, /test "\$name" != environment-release\.json/) assert.doesNotMatch(workflow, /bootstrap\.manifest\.json bootstrap\.manifest\.sig\.json/) assert.doesNotMatch(workflow, /\.artifacts\[\]\.url/) assert.doesNotMatch(workflow, /environment-v\$\{ENVIRONMENT_VERSION\}\.tar\.gz/) assert.doesNotMatch(workflow, /uses: \.\/\.github\/workflows\/docker\.yaml/) assert.doesNotMatch(workflow, /environment: production-image|DOCKER_TOKEN/) assert.equal(workflow.split(gotifyWorkflow).length - 1, 0) assert.doesNotMatch(workflow, /platform-\$\{TARGET_SEQUENCE\}|DSH Platform \$\{TARGET_SEQUENCE\}/) assert.doesNotMatch(workflow, /RECOVERY_PRIVATE|secrets: inherit/) }) test('successful signed targets notify independently from image approval', async () => { const workflow = await readFile(notificationsUrl, 'utf8') assert.match(workflow, /workflow_run:/) assert.match(workflow, /Publish Supported Platform Target/) assert.match(workflow, /github\.event\.workflow_run\.name == 'Publish Supported Platform Target'/) assert.match(workflow, /github\.event\.workflow_run\.conclusion == 'success'/) assert.match(workflow, /github\.event\.workflow_run\.conclusion == 'failure'/) assert.match(workflow, /DSH 正式发布失败/) assert.match(workflow, /production-image/) assert.match(workflow, /actions\/workflows\/docker\.yaml/) assert.equal(workflow.split(gotifyWorkflow).length - 1, 1) assert.equal((workflow.match(/^ notify-result:/gm) ?? []).length, 1) assert.doesNotMatch(workflow, /actions\/checkout|\brun:/) }) test('Docker publication consumes one signed channel target and mirrors only standard images to GHCR', async () => { const workflow = await readFile(dockerUrl, 'utf8') assert.match(workflow, /workflow_run:/) assert.match(workflow, /Publish Supported Platform Target/) assert.match(workflow, /github\.event\.workflow_run\.conclusion == 'success'/) assert.match(workflow, /github\.event\.workflow_run\.head_sha/) assert.match(workflow, /environment: production-image/) assert.match(workflow, /contents: read\n packages: write/) assert.match(workflow, /git -C channel log --format=%H -- channel\.json/) assert.match(workflow, /No signed release-channel target matches source commit/) assert.match(workflow, /latestSupportedDsh/) assert.match(workflow, /channel\/targets\/\$sequence/) assert.match(workflow, /verify-image-release\.mjs/) assert.equal((workflow.match(/SIGNED_IMAGE_INPUT=true/g) ?? []).length, 4) assert.match(workflow, /PLATFORM_REVISION=\$\{\{ steps\.channel\.outputs\.source_commit \}\}/) assert.match(workflow, /ENVIRONMENT_VERSION=\$\{\{ steps\.signed-target\.outputs\.environment_version \}\}/) assert.match(workflow, /TARGET_SEQUENCE=\$\{\{ steps\.signed-target\.outputs\.sequence \}\}/) assert.match(workflow, /cache: npm/) assert.match(workflow, /cache-dependency-path:[\s\S]*source\/container\/control-plane\/services\/management\/package-lock\.json[\s\S]*source\/container\/environment\/resources\/plugins\/platform-management\/package\/package-lock\.json/) assert.match(workflow, /npm ci --omit=dev --ignore-scripts --no-audit --no-fund --prefix container\/control-plane\/services\/management/) assert.match(workflow, /npm ci --omit=dev --ignore-scripts --no-audit --no-fund --legacy-peer-deps --prefix container\/environment\/resources\/plugins\/platform-management\/package/) assert.match(workflow, /DOCKERHUB_IMAGE: szcq\/deepseek-harness/) assert.match(workflow, /GHCR_IMAGE: ghcr\.io\/\$\{\{ github\.repository \}\}/) assert.match(workflow, /\$\{GHCR_IMAGE\}:\$\{ENVIRONMENT_VERSION\}/) assert.match(workflow, /\$\{GHCR_IMAGE\}:\$\{major\}\.\$\{minor\}/) assert.match(workflow, /\$\{GHCR_IMAGE\}:dsh-\$\{DSH_VERSION\}/) assert.match(workflow, /\$\{DOCKERHUB_IMAGE\}:\$\{DSH_VERSION\}-devtools/) const versionedDevtools = workflow.indexOf('- name: Push versioned devtools image to Docker Hub') const versionedStandard = workflow.indexOf('- name: Push versioned standard image to Docker Hub and GHCR') const rollingTags = workflow.indexOf('- name: Promote Docker Hub rolling tags') assert.ok(versionedDevtools >= 0) assert.ok(versionedDevtools < versionedStandard) assert.ok(versionedStandard < rollingTags) const promotion = workflow.slice(rollingTags, workflow.indexOf('- name:', rollingTags + 1)) assert.ok(promotion.indexOf(':latest-devtools"') < promotion.indexOf(':latest"')) assert.equal(workflow.split(gotifyWorkflow).length - 1, 1) assert.match(workflow, /notify-result:[\s\S]*needs\.build\.result == 'success'[\s\S]*needs\.build\.result == 'failure'/) assert.match(workflow, /DSH 镜像发布失败/) assert.doesNotMatch(workflow, /\$\{GHCR_IMAGE\}:[^\n]*devtools/) assert.doesNotMatch(workflow, /workflow_call:|gh release|DSH_RELEASE_PRIVATE_KEY|prepare-release\.mjs/) })