Skip to content

Extend release manifest schema #66

Extend release manifest schema

Extend release manifest schema #66

Workflow file for this run

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"