Extend release manifest schema #66
Workflow file for this run
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: PR Fast CI | |
| on: | |
| pull_request: | |
| types: [opened, edited, synchronize, reopened, ready_for_review] | |
| concurrency: | |
| group: pr-fast-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| env: | |
| NODE_VERSION: '20' | |
| PYTHON_VERSION: '3.12' | |
| defaults: | |
| run: | |
| shell: bash | |
| jobs: | |
| changes: | |
| name: Detect Relevant Changes | |
| runs-on: ['self-hosted', 'synology', 'shell-only', 'public'] | |
| outputs: | |
| app: ${{ steps.filter.outputs.app }} | |
| ci: ${{ steps.filter.outputs.ci }} | |
| steps: | |
| - uses: dorny/paths-filter@v3 | |
| id: filter | |
| with: | |
| filters: | | |
| app: | |
| - 'project.bootstrap.yaml' | |
| - 'AGENTS.md' | |
| - 'CONTRIBUTING.md' | |
| - '.github/PULL_REQUEST_TEMPLATE.md' | |
| - '.githooks/**' | |
| - '.github/workflows/**' | |
| - 'scripts/**' | |
| - 'docs/bootstrap/**' | |
| - 'README.md' | |
| - 'docs/**' | |
| ci: | |
| - 'project.bootstrap.yaml' | |
| - 'AGENTS.md' | |
| - 'CONTRIBUTING.md' | |
| - '.github/PULL_REQUEST_TEMPLATE.md' | |
| - '.githooks/**' | |
| - '.github/workflows/**' | |
| - 'scripts/**' | |
| - 'docs/bootstrap/**' | |
| - '.env.example' | |
| - 'CODEOWNERS' | |
| fast-checks: | |
| name: Fast Checks | |
| runs-on: ['self-hosted', 'synology', 'shell-only', 'public'] | |
| timeout-minutes: 15 | |
| needs: changes | |
| if: >- | |
| github.event.pull_request.draft == false && | |
| (needs.changes.outputs.app == 'true' || needs.changes.outputs.ci == 'true') | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| - name: Run fast checks | |
| run: bash scripts/ci/run-fast-checks.sh | |
| validate-pr-description: | |
| name: Validate PR Description | |
| runs-on: ['self-hosted', 'synology', 'shell-only', 'public'] | |
| timeout-minutes: 5 | |
| if: github.event.pull_request.draft == false | |
| env: | |
| PR_BODY: ${{ github.event.pull_request.body }} | |
| steps: | |
| - name: Require generated PR template content | |
| run: | | |
| failed=0 | |
| require_line() { | |
| local line="$1" | |
| if ! grep -Fqx "$line" <<<"$PR_BODY"; then | |
| echo "Missing required PR section: $line" | |
| failed=1 | |
| fi | |
| } | |
| require_line "## Summary" | |
| require_line "## Governing Issue" | |
| require_line "## Validation" | |
| require_line "## Bootstrap Governance" | |
| require_line "## Merge Automation" | |
| require_line "## Notes" | |
| if grep -Eiq 'Closes #$|#<issue-number>|what changed|why it changed|notable tradeoffs|migration or rollout notes|follow-up work if any' <<<"$PR_BODY"; then | |
| echo "PR body still contains template placeholder text." | |
| failed=1 | |
| fi | |
| if ! grep -Eiq '(^|[[:space:]-])((close[sd]?|fix(e[sd])?|resolve[sd]?)[[:space:]]+#[0-9]+|no issue is linked|no linked issue|without a linked issue|no governing issue)' <<<"$PR_BODY"; then | |
| echo "PR body must close/link an issue or explicitly explain why no issue is linked." | |
| failed=1 | |
| fi | |
| if ! grep -Eiq '(^|[[:space:]-])(\[[xX]\]|not run|not applicable|n/a)' <<<"$PR_BODY"; then | |
| echo "PR body must include validation evidence, a checked validation item, or a reason validation was not run." | |
| failed=1 | |
| fi | |
| if ! grep -Eiq '(auto-merge is enabled|auto-merge enabled|auto merge is enabled|auto merge enabled|auto-merge.*(unavailable|unsafe|blocked|not supported)|auto merge.*(unavailable|unsafe|blocked|not supported))' <<<"$PR_BODY"; then | |
| echo "PR body must state that auto-merge is enabled or explain why it is unavailable or unsafe." | |
| failed=1 | |
| fi | |
| exit "$failed" | |
| validate-secrets: | |
| name: Validate Secrets | |
| runs-on: ['self-hosted', 'synology', 'shell-only', 'public'] | |
| timeout-minutes: 10 | |
| if: github.event.pull_request.draft == false | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| - name: Scan repository for secret patterns | |
| run: bash scripts/check-detect-secrets.sh --all-files | |
| ci-gate: | |
| name: CI Gate | |
| runs-on: ['self-hosted', 'synology', 'shell-only', 'public'] | |
| if: always() | |
| needs: | |
| - changes | |
| - fast-checks | |
| - validate-pr-description | |
| - validate-secrets | |
| steps: | |
| - name: Check required PR jobs | |
| env: | |
| RESULTS: >- | |
| changes=${{ needs.changes.result }} | |
| fast-checks=${{ needs.fast-checks.result }} | |
| validate-pr-description=${{ needs.validate-pr-description.result }} | |
| validate-secrets=${{ needs.validate-secrets.result }} | |
| run: | | |
| failed=0 | |
| for entry in $RESULTS; do | |
| job="${entry%%=*}" | |
| status="${entry##*=}" | |
| if [[ "$status" == "success" || "$status" == "skipped" ]]; then | |
| echo "OK $job => $status" | |
| else | |
| echo "FAIL $job => $status" | |
| failed=1 | |
| fi | |
| done | |
| exit "$failed" |