mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 07:15:47 +00:00
bf38288feb
* ci(release): split channel pipelines and automate version transitions Introduce dedicated next/release orchestration workflows backed by a reusable publish pipeline with RC/final package version updates and post-release main dev bump PRs. Add a strict release process SOP with RC freeze, hotfix override, and mandatory backport rules. * ci(release): gate main-to-next promotion on green CI Add a dedicated workflow that validates main branch checks/statuses and block the promote-main-to-next flow unless main is green. Update the release SOP to reflect the enforced pre-promotion validation. * ci(release): fix channel promotion edge cases and policy gaps Switch channel promotions to reset-based snapshots with force-with-lease pushes, stop auto-merging channel nix-refresh PRs, and guard main dev bump against version downgrades. Add RC changelog fallback, require AUR release updates in SOP, and extend npmDepsHash sync to main/next/release pushes. * docs(release): clarify backport and nix refresh survivability rules Require RC fix backports to reach main before the next main-to-next promotion, and document that channel-local nix refresh PRs are advisory unless equivalent changes are merged into main.
78 lines
2.4 KiB
YAML
78 lines
2.4 KiB
YAML
name: Validate Main Green CI
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
branch:
|
|
description: "Branch to validate"
|
|
required: false
|
|
default: main
|
|
type: string
|
|
workflow_call:
|
|
inputs:
|
|
branch:
|
|
required: false
|
|
default: main
|
|
type: string
|
|
|
|
jobs:
|
|
validate:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
checks: read
|
|
statuses: read
|
|
steps:
|
|
- name: validate branch checks are green
|
|
uses: actions/github-script@v7
|
|
env:
|
|
TARGET_BRANCH: ${{ inputs.branch || github.event.inputs.branch || 'main' }}
|
|
with:
|
|
script: |
|
|
const owner = context.repo.owner;
|
|
const repo = context.repo.repo;
|
|
const branch = process.env.TARGET_BRANCH || "main";
|
|
|
|
const branchResp = await github.rest.repos.getBranch({ owner, repo, branch });
|
|
const sha = branchResp.data.commit.sha;
|
|
core.info(`Validating checks for ${branch} @ ${sha}`);
|
|
|
|
const combined = await github.rest.repos.getCombinedStatusForRef({
|
|
owner,
|
|
repo,
|
|
ref: sha,
|
|
});
|
|
const statusState = combined.data.state;
|
|
const statusCount = combined.data.statuses.length;
|
|
core.info(`Combined status state: ${statusState} (${statusCount} status contexts)`);
|
|
|
|
const checks = await github.paginate(github.rest.checks.listForRef, {
|
|
owner,
|
|
repo,
|
|
ref: sha,
|
|
per_page: 100,
|
|
});
|
|
|
|
if (checks.length === 0 && statusCount === 0) {
|
|
core.setFailed(`No checks/statuses found for ${branch}. Refusing promotion.`);
|
|
return;
|
|
}
|
|
|
|
const badChecks = checks.filter((c) => {
|
|
if (c.status !== "completed") return true;
|
|
return !["success", "neutral", "skipped"].includes(c.conclusion || "");
|
|
});
|
|
|
|
if (badChecks.length > 0) {
|
|
const details = badChecks.map((c) => `${c.name}: status=${c.status}, conclusion=${c.conclusion}`).join("\n");
|
|
core.setFailed(`Branch ${branch} is not green.\n${details}`);
|
|
return;
|
|
}
|
|
|
|
if (!["success", "neutral"].includes(statusState)) {
|
|
core.setFailed(`Combined status is ${statusState} for ${branch}.`);
|
|
return;
|
|
}
|
|
|
|
core.info(`Branch ${branch} is green.`);
|