Merge pull request #7581 from deepseek-harness/fix/merge-approve-jobs

ci: decide the review verdict in one Approve Check job
This commit is contained in:
imccyu
2026-10-30 16:15:02 +08:00
committed by GitHub
parent ea9912523d
commit 93e28b1418
3 changed files with 20 additions and 38 deletions
+1 -1
View File
@@ -4,6 +4,6 @@ Run jobs on Windows runners (`windows-*` labels) under native `pwsh`. Native Win
The manual [Windows packaging workflow](workflows/windows-package.yml) uses the dedicated self-hosted Windows x64 label `dsh-win-package-trial` under native `pwsh`; preserve this routing separately from the automatic CI lanes.
The merge checks run from three workflows named `Policy`, which run on `pull_request_target` so their definitions come from master, and call the `deepseek-harness-check` action directly: `pr-check-on-head-branch.yml` on pull-request updates gives `Policy / Master Change` and `Policy / Pre-Merge Check`, `pr-check-after-approve.yml` on pull-request updates and submitted or dismissed reviews gives `Policy / Approve Check` and `Policy / Reviewer Evaluate`, and `pr-check-on-base-branch.yml` on master pushes re-runs the head-branch checks as `Policy / Recheck`. Branch rules require those check names, so keep the job names and the workflow name. Each check reads its mode from a repository variable: `MERGE_POLICY_MASTER_DIFF`, `MERGE_POLICY_PRE_MERGE`, `MERGE_POLICY_HEAD_DIFF`, and `MERGE_POLICY_REVIEW`, each `off` (skip), `report` (run without failing the job), or `block` (fail the job); a missing value or an unknown one counts as `report`. `Policy / Pre-Merge Check` merges the commit `Policy / Master Change` reports, so it runs only after that job and stays off while `MERGE_POLICY_MASTER_DIFF` is `off`; a merge it cannot do and a build that fails both follow its own mode, so `report` warns and skips the build while `block` fails the job. `Policy / Pre-Merge Check` runs `scripts/pre-merge-check.ts` under plain Node and knows nothing else about the merged tree: that script checks the released manifests against the root version, installs, and builds the Host and Client contracts, so change it in one pull request together with the build it orchestrates.
The merge checks run from three workflows named `Policy`, which run on `pull_request_target` so their definitions come from master, and call the `deepseek-harness-check` action directly: `pr-check-on-head-branch.yml` on pull-request updates gives `Policy / Master Change` and `Policy / Pre-Merge Check`, `pr-check-after-approve.yml` on pull-request updates and submitted or dismissed reviews gives `Policy / Approve Check`, which also publishes the review verdict as the check run `Policy / Reviewer Check`, and `pr-check-on-base-branch.yml` on master pushes re-runs the head-branch checks as `Policy / Recheck`. Branch rules require those check names, so keep the job names and the workflow name. Each job reads its mode from a repository variable: `MERGE_POLICY_MASTER_DIFF`, `MERGE_POLICY_PRE_MERGE`, and `MERGE_POLICY_HEAD_DIFF`, each `off` (skip), `report` (run without failing the job), or `block` (fail the job); a missing value or an unknown one counts as `report`. `MERGE_POLICY_HEAD_DIFF` decides whether `Policy / Approve Check` runs and fails; while it runs, `Policy / Reviewer Check` is published whatever that mode says, with `success` when every file that needs review has one and `action_required` with the reviewers to ask otherwise. `Policy / Pre-Merge Check` merges the commit `Policy / Master Change` reports, so it runs only after that job and stays off while `MERGE_POLICY_MASTER_DIFF` is `off`; a merge it cannot do and a build that fails both follow its own mode, so `report` warns and skips the build while `block` fails the job. `Policy / Pre-Merge Check` runs `scripts/pre-merge-check.ts` under plain Node and knows nothing else about the merged tree: that script checks the released manifests against the root version, installs, and builds the Host and Client contracts, so change it in one pull request together with the build it orchestrates.
The manual Desktop publication workflow selects a successful package run and attempt, then routes each retained build through `DESKTOP_PUBLISH_RUNNERS` to its original machine's unique label. Keep Windows run steps on native PowerShell and Mac run steps on the default POSIX shell; shared entrypoints are Node scripts. Test and production jobs use separate `desktop-test` and `desktop-production` approval Environments after a credential-free preparation job.
+4 -36
View File
@@ -14,47 +14,15 @@ concurrency:
jobs:
approve:
name: Approve Check
# Each check runs only while its repository variable is neither empty nor `off`; otherwise the job is skipped.
# Skipped while MERGE_POLICY_HEAD_DIFF is empty or `off`; otherwise the job fails by that mode and publishes
# `Policy / Reviewer Check` whatever that mode says.
if: ${{ vars.MERGE_POLICY_HEAD_DIFF != '' && vars.MERGE_POLICY_HEAD_DIFF != 'off' }}
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
pull-requests: read
steps:
# The head checkout is only the Git repository the check fetches into; it needs no files and runs no code.
- uses: actions/checkout@v7.0.1
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 1
filter: blob:none
sparse-checkout: README.md
sparse-checkout-cone-mode: false
- uses: actions/setup-node@v7.0.0
with:
node-version: '24'
package-manager-cache: false
- uses: deepseek-harness/deepseek-harness-check@master
env:
CHECK_MODE: ${{ vars.MERGE_POLICY_HEAD_DIFF }}
with:
check: head-diff
base-branch: ${{ github.event.pull_request.base.ref }}
head-sha: ${{ github.event.pull_request.head.sha }}
pr-number: ${{ github.event.pull_request.number }}
pr-author: ${{ github.event.pull_request.user.login }}
review:
name: Reviewer Evaluate
if: ${{ vars.MERGE_POLICY_REVIEW != '' && vars.MERGE_POLICY_REVIEW != 'off' }}
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
pull-requests: read
# The check posts its verdict as a check run of its own.
# The check posts the review verdict as a check run of its own.
checks: write
steps:
# The head checkout is only the Git repository the check fetches into; it needs no files and runs no code.
@@ -84,7 +52,7 @@ jobs:
- uses: deepseek-harness/deepseek-harness-check@master
env:
CHECK_MODE: ${{ vars.MERGE_POLICY_REVIEW }}
CHECK_MODE: ${{ vars.MERGE_POLICY_HEAD_DIFF }}
CHECK_TOKEN: ${{ steps.token.outputs.token }}
with:
check: review
+15 -1
View File
@@ -1771,7 +1771,7 @@ describe('Policy workflow shells', () => {
describe('Policy workflows', () => {
const workflows = [
['pr-check-on-head-branch.yml', ['master']],
['pr-check-after-approve.yml', ['approve', 'review']],
['pr-check-after-approve.yml', ['approve']],
] as const
function stepsOf(job: Record<string, unknown>): Record<string, unknown>[] {
@@ -1794,6 +1794,20 @@ describe('Policy workflows', () => {
}
})
it('decides the review verdict in one Approve Check job that can publish the check run', () => {
const workflow = loadWorkflow('.github/workflows/pr-check-after-approve.yml')
if (!isRecord(workflow.jobs)) throw new TypeError('the workflow must define jobs')
expect(Object.keys(workflow.jobs)).toEqual(['approve'])
const job = workflow.jobs.approve
if (!isRecord(job) || !isRecord(job.permissions)) throw new TypeError('the approve job must declare permissions')
expect(job.name).toBe('Approve Check')
expect(job.permissions.checks).toBe('write')
const check = stepsOf(job).find(step => typeof step.uses === 'string' && step.uses.startsWith('deepseek-harness/deepseek-harness-check@'))
if (check === undefined || !isRecord(check.env)) throw new TypeError('the job must run the check action with env')
expect(String(check.env.CHECK_MODE)).toContain('vars.MERGE_POLICY_HEAD_DIFF')
expect(JSON.stringify(workflow)).not.toContain('MERGE_POLICY_REVIEW')
})
it('keeps the pre-merge build behind the merge step, which honours the mode on its failures', () => {
const steps = stepsOf(workflowJob(loadWorkflow('.github/workflows/pr-check-on-head-branch.yml'), 'pre-merge'))
const merge = steps.findIndex(step => step.id === 'merge')