mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-12 05:36:40 +00:00
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
184 lines
5.6 KiB
YAML
184 lines
5.6 KiB
YAML
name: "⚡ CI: Push"
|
|
|
|
concurrency:
|
|
group: global-ci-${{ github.repository }}-${{ github.ref_name }}
|
|
cancel-in-progress: false
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
- "feature/**"
|
|
- "hotfix/**"
|
|
- "fix/**"
|
|
|
|
permissions:
|
|
contents: write
|
|
packages: write
|
|
actions: write
|
|
security-events: write
|
|
|
|
jobs:
|
|
# Skip a branch-creation push only when the pushed commit is already
|
|
# contained in origin/main. Fresh commits outside main still run CI.
|
|
run-policy:
|
|
name: 🧭 Decide CI policy
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
should_run: ${{ steps.decide.outputs.should_run }}
|
|
skip_reason: ${{ steps.decide.outputs.skip_reason }}
|
|
commit_in_main: ${{ steps.decide.outputs.commit_in_main }}
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Fetch main
|
|
if: github.event.created == true
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
git fetch origin main:refs/remotes/origin/main --force
|
|
|
|
- name: Decide whether CI should run for this push
|
|
id: decide
|
|
env:
|
|
GITHUB_EVENT_CREATED: ${{ github.event.created }}
|
|
shell: bash
|
|
run: bash scripts/meta/resolve/push_ci_policy.sh
|
|
|
|
skip-branch-creation-from-main:
|
|
name: ⏭️ Skip branch creation from main
|
|
needs: run-policy
|
|
if: needs.run-policy.outputs.should_run != 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Explain skip
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
echo "Skipping CI for branch creation because commit ${GITHUB_SHA} is already contained in origin/main."
|
|
echo "Reason: ${{ needs.run-policy.outputs.skip_reason }}"
|
|
|
|
pick-distro:
|
|
if: needs.run-policy.outputs.should_run == 'true'
|
|
needs: run-policy
|
|
name: 🎲 Pick distro(s)
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
distros: ${{ steps.pick.outputs.distros }}
|
|
is_version: ${{ steps.pick.outputs.is_version }}
|
|
version_tag: ${{ steps.pick.outputs.version_tag }}
|
|
steps:
|
|
- name: Checkout (with tags)
|
|
uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 0
|
|
fetch-tags: true
|
|
|
|
- id: pick
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
ALL_DISTROS=(arch debian ubuntu fedora centos)
|
|
|
|
version_tag="$(
|
|
git tag --points-at "${GITHUB_SHA}" \
|
|
| grep -E '^v[0-9]+(\.[0-9]+)*$' \
|
|
| head -n 1 || true
|
|
)"
|
|
|
|
if [[ -n "${version_tag}" ]]; then
|
|
echo "is_version=true" >> "$GITHUB_OUTPUT"
|
|
echo "version_tag=${version_tag}" >> "$GITHUB_OUTPUT"
|
|
distros="${ALL_DISTROS[*]}"
|
|
echo "🎯 Commit ${GITHUB_SHA} has version tag ${version_tag} → running ALL distros"
|
|
else
|
|
echo "is_version=false" >> "$GITHUB_OUTPUT"
|
|
echo "version_tag=" >> "$GITHUB_OUTPUT"
|
|
one="$(printf "%s\n" "${ALL_DISTROS[@]}" | shuf -n 1)"
|
|
distros="${one}"
|
|
echo "🎲 No version tag on commit → picked distro: ${one}"
|
|
fi
|
|
|
|
echo "distros=${distros}" >> "$GITHUB_OUTPUT"
|
|
echo "=== Selected distros: ${distros} ==="
|
|
echo "=== is_version: $(grep -E '^is_version=' "$GITHUB_OUTPUT" | tail -n 1) ==="
|
|
echo "=== version_tag: $(grep -E '^version_tag=' "$GITHUB_OUTPUT" | tail -n 1) ==="
|
|
|
|
ci-orchestrator:
|
|
if: needs.run-policy.outputs.should_run == 'true'
|
|
name: 🎶 Orchestrate CI
|
|
needs:
|
|
- run-policy
|
|
- pick-distro
|
|
uses: ./.github/workflows/ci-orchestrator.yml
|
|
with:
|
|
# ci-orchestrator expects a space-separated list → here it's either one or many
|
|
distros: ${{ needs.pick-distro.outputs.distros }}
|
|
secrets: inherit
|
|
|
|
# Guard job: only allow version releases if the tag commit is contained in origin/main
|
|
release-guard:
|
|
name: "🛡️ Guard release"
|
|
if: needs.run-policy.outputs.should_run == 'true' && needs.pick-distro.outputs.is_version == 'true'
|
|
needs:
|
|
- run-policy
|
|
- pick-distro
|
|
- ci-orchestrator
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
allowed: ${{ steps.guard.outputs.allowed }}
|
|
steps:
|
|
- name: Checkout (with full history)
|
|
uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 0
|
|
fetch-tags: true
|
|
|
|
- name: Fetch main
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
git fetch origin main:refs/remotes/origin/main --force
|
|
|
|
- name: "Guard: tag commit must be contained in origin/main"
|
|
id: guard
|
|
shell: bash
|
|
env:
|
|
VERSION_TAG: ${{ needs.pick-distro.outputs.version_tag }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
if [[ -z "${VERSION_TAG}" ]]; then
|
|
echo "allowed=false" >> "$GITHUB_OUTPUT"
|
|
echo "⛔ No version tag detected for this commit"
|
|
exit 0
|
|
fi
|
|
|
|
tag="${VERSION_TAG}"
|
|
tag_sha="$(git rev-list -n 1 "${tag}")"
|
|
echo "Tag: ${tag} -> ${tag_sha}"
|
|
|
|
if git merge-base --is-ancestor "${tag_sha}" "origin/main"; then
|
|
echo "allowed=true" >> "$GITHUB_OUTPUT"
|
|
echo "✅ Tag commit is on origin/main"
|
|
else
|
|
echo "allowed=false" >> "$GITHUB_OUTPUT"
|
|
echo "⛔ Tag commit is NOT on origin/main"
|
|
fi
|
|
|
|
release-version:
|
|
name: 🚀 Release version
|
|
needs:
|
|
- run-policy
|
|
- pick-distro
|
|
- release-guard
|
|
if: needs.run-policy.outputs.should_run == 'true' && needs.release-guard.outputs.allowed == 'true'
|
|
uses: ./.github/workflows/release-version.yml
|
|
with:
|
|
tag: ${{ needs.pick-distro.outputs.version_tag }}
|
|
secrets: inherit
|