Skip to content
Open
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
14 changes: 10 additions & 4 deletions .github/workflows/sync-main-to-develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ on:
description: 'Release version to sync, e.g. 1.2.3. Defaults to packages/vchart version on main.'
required: false
type: string
pull_request:
# Release PR heads use [skip ci], which suppresses pull_request workflows.
# pull_request_target still runs on merge; this job only checks out main.
pull_request_target:
types:
- closed
branches:
Expand All @@ -17,7 +19,11 @@ jobs:
sync_main_to_develop:
if: >-
github.event_name == 'workflow_dispatch' ||
(github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'release/'))
(
github.event.pull_request.merged == true &&
startsWith(github.event.pull_request.head.ref, 'release/') &&
github.event.pull_request.head.repo.full_name == github.repository
)

runs-on: macos-latest

Expand All @@ -44,7 +50,7 @@ jobs:

- name: Configure git remote for workflow-created branches
env:
GH_TOKEN: ${{ secrets.CREATE_TAG_RELEASE_TOKEN || github.token }}
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
Expand Down Expand Up @@ -128,7 +134,7 @@ jobs:

- name: Create Pull Request to develop
env:
GH_TOKEN: ${{ secrets.CREATE_TAG_RELEASE_TOKEN || github.token }}
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
BRANCH="${{ steps.sync_branch.outputs.sync_branch }}"
Expand Down
17 changes: 13 additions & 4 deletions common/scripts/verify-release-workflows.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ function assertFallbackGhToken(step, context) {
assert(step && step.env && step.env.GH_TOKEN === '${{ secrets.CREATE_TAG_RELEASE_TOKEN || github.token }}', `${context} must use PAT fallback GH_TOKEN`);
}

function assertGithubToken(step, context) {
assert(step && step.env && step.env.GH_TOKEN === '${{ github.token }}', `${context} must use GitHub Actions bot token`);
}

function assertStepIfIncludes(step, expected, context) {
assert(step, `${context} step must exist`);
assert(typeof step.if === 'string' && step.if.includes(expected), `${context} if must include ${expected}`);
Expand Down Expand Up @@ -164,21 +168,26 @@ function run() {

const syncOn = getOn(syncMain);
assert(hasOwn(syncOn, 'workflow_dispatch'), 'sync-main-to-develop.yml must support workflow_dispatch recovery');
assert(!hasOwn(syncOn, 'pull_request'), 'sync-main-to-develop.yml must not use pull_request because release heads use [skip ci]');
assert(hasOwn(syncOn, 'pull_request_target'), 'sync-main-to-develop.yml must use pull_request_target for release PR merge events');
assertArrayIncludes(syncOn.pull_request_target.types, ['closed'], 'sync-main-to-develop.yml pull_request_target types');
assertArrayIncludes(syncOn.pull_request_target.branches, ['main'], 'sync-main-to-develop.yml pull_request_target branches');
assert(
syncMain.data.jobs.sync_main_to_develop.if &&
syncMain.data.jobs.sync_main_to_develop.if.includes("github.event_name == 'workflow_dispatch'"),
'sync-main-to-develop.yml job must allow workflow_dispatch'
syncMain.data.jobs.sync_main_to_develop.if.includes("github.event_name == 'workflow_dispatch'") &&
syncMain.data.jobs.sync_main_to_develop.if.includes("github.event.pull_request.head.repo.full_name == github.repository"),
'sync-main-to-develop.yml job must allow workflow_dispatch and only trust same-repo release PRs'
);
const syncCheckout = getStep(syncMain, 'sync_main_to_develop', 'Checkout');
assert(syncCheckout && syncCheckout.with && syncCheckout.with.ref === 'main', 'sync-main-to-develop.yml must checkout main explicitly');
assertFallbackGhToken(getStep(syncMain, 'sync_main_to_develop', 'Configure git remote for workflow-created branches'), 'sync-main remote setup');
assertGithubToken(getStep(syncMain, 'sync_main_to_develop', 'Configure git remote for workflow-created branches'), 'sync-main remote setup');
assertRunIncludes(
getStep(syncMain, 'sync_main_to_develop', 'Compute sync branch name and check existence'),
'^[0-9]+\\.[0-9]+\\.[0-9]+$',
'sync-main-to-develop.yml version validation'
);
const syncPrStep = getStep(syncMain, 'sync_main_to_develop', 'Create Pull Request to develop');
assertFallbackGhToken(syncPrStep, 'sync-main PR creation');
assertGithubToken(syncPrStep, 'sync-main PR creation');
assert(!syncPrStep.if, 'sync-main PR creation must run even when the sync branch already exists');

const dispatchOn = getOn(developDispatch);
Expand Down
Loading