Merge branch 'dependabot/npm_and_yarn/npm-root-4227cb135b' into Devel… #635
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Development Merge Check | |
| # Advisory, NON-BLOCKING check for the team convention that branches merge into | |
| # Development before main. | |
| # | |
| # It is a single check on the PR - this job's own pass/fail: | |
| # green when the PR head commit is already in Development | |
| # red when it is not (a reminder, not a hard failure; it does not block a | |
| # merge unless someone marks it a required check) | |
| # | |
| # "In Development" is detected by ancestry, because the team merges into | |
| # Development with a direct `git merge` + push (`npm run merge`), not a PR, so the | |
| # PR head becomes an ancestor of Development. A merged-PR lookup is kept as a | |
| # squash-merge fallback. | |
| # | |
| # Triggers: | |
| # pull_request - evaluate this PR's head on every commit (this is the verdict). | |
| # push: Development - a branch can land in Development without a new PR commit, | |
| # so re-run each still-red PR's check to flip it green. | |
| # workflow_dispatch - manual refresh. | |
| on: | |
| pull_request: | |
| types: [opened, reopened, synchronize, ready_for_review] | |
| branches: [main] | |
| push: | |
| branches: [Development] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| actions: write | |
| concurrency: | |
| group: dev-merge-check-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| development-merge-check: | |
| name: Development merge check (advisory) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check Development merge status | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| with: | |
| script: | | |
| const DEV_BRANCH = 'Development'; | |
| const WORKFLOW = 'development-merge-check.yml'; | |
| const { owner, repo } = context.repo; | |
| // Detail string if the head is in Development, else null. | |
| async function mergedDetail(headRef, headSha, headOwner) { | |
| // Direct merge: npm run merge makes a real merge commit, so the head | |
| // is contained in Development ("behind" or "identical"). | |
| try { | |
| const cmp = await github.rest.repos.compareCommitsWithBasehead({ | |
| owner, repo, basehead: `${DEV_BRANCH}...${headSha}`, | |
| }); | |
| if (cmp.data.status === 'behind' || cmp.data.status === 'identical') { | |
| return `Branch "${headRef}" is on ${DEV_BRANCH}: its commits (through ${headSha.slice(0, 7)}) are already in ${DEV_BRANCH}.`; | |
| } | |
| } catch (e) { | |
| core.info(`compare ${DEV_BRANCH}...${headSha} failed: ${e.message}`); | |
| } | |
| // Fallback: a PR/squash merge into Development. | |
| const devPulls = await github.paginate(github.rest.pulls.list, { | |
| owner, repo, state: 'closed', base: DEV_BRANCH, | |
| head: `${headOwner}:${headRef}`, per_page: 100, | |
| }); | |
| const mergedPr = devPulls.find((p) => p.merged_at); | |
| return mergedPr | |
| ? `Branch "${headRef}" is on ${DEV_BRANCH} (merged via PR #${mergedPr.number}).` | |
| : null; | |
| } | |
| // pull_request: this job's pass/fail IS the advisory check for the PR. | |
| if (context.eventName === 'pull_request') { | |
| const pr = context.payload.pull_request; | |
| const headOwner = pr.head.repo ? pr.head.repo.owner.login : owner; | |
| const detail = await mergedDetail(pr.head.ref, pr.head.sha, headOwner); | |
| if (detail) { | |
| core.info(detail); | |
| } else { | |
| core.setFailed( | |
| `Branch "${pr.head.ref}" is not on ${DEV_BRANCH} yet. Team workflow ` + | |
| `routes branches through ${DEV_BRANCH} before main. Advisory only; ` + | |
| `it does not block merging.`, | |
| ); | |
| } | |
| return; | |
| } | |
| // push to Development / manual dispatch: a branch may have just landed | |
| // in Development without a new PR commit. Re-run each still-red PR's | |
| // check so its verdict refreshes against the updated Development. | |
| const prs = await github.paginate(github.rest.pulls.list, { | |
| owner, repo, state: 'open', base: 'main', per_page: 100, | |
| }); | |
| const runs = await github.paginate(github.rest.actions.listWorkflowRuns, { | |
| owner, repo, workflow_id: WORKFLOW, event: 'pull_request', per_page: 100, | |
| }); | |
| const latestBySha = new Map(); | |
| for (const r of runs) { | |
| if (!latestBySha.has(r.head_sha)) latestBySha.set(r.head_sha, r); | |
| } | |
| for (const pr of prs) { | |
| const run = latestBySha.get(pr.head.sha); | |
| if (run?.conclusion === 'failure') { | |
| try { | |
| await github.rest.actions.reRunWorkflowFailedJobs({ | |
| owner, repo, run_id: run.id, | |
| }); | |
| core.info(`PR #${pr.number}: re-running advisory check (was red).`); | |
| } catch (e) { | |
| core.warning(`PR #${pr.number}: re-run failed: ${e.message}`); | |
| } | |
| } | |
| } |