Repository navigation
feat(maintenance): bound Docker image and build-cache retention #798
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: Validate ci-fleet prototype | |
| on: | |
| pull_request: | |
| # `edited` revalidates the title when a contributor retitles the PR: the | |
| # required check would otherwise stay green for the same head SHA. | |
| types: [opened, synchronize, reopened, edited] | |
| push: | |
| branches: [main] | |
| tags: ['**'] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: validate-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| commit-convention: | |
| name: Enforce conventional commits and pull-request title | |
| if: ${{ github.event_name != 'push' || github.event.deleted == false }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Reject updates to published tags | |
| if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && github.event.created == false }} | |
| run: | | |
| echo "published tags must not be moved" >&2 | |
| exit 1 | |
| - name: Check out repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| fetch-depth: 0 | |
| - name: Load current main commit validator | |
| env: | |
| EVENT_NAME: ${{ github.event_name }} | |
| BASE_REF: ${{ github.event.pull_request.base.ref }} | |
| HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} | |
| run: | | |
| git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main | |
| TRUSTED_SHA="$(git rev-parse origin/main)" | |
| validator="$RUNNER_TEMP/trusted-validator.py" | |
| if git cat-file -e "$TRUSTED_SHA:scripts/validate_commits.py" 2>/dev/null; then | |
| git show "$TRUSTED_SHA:scripts/validate_commits.py" >"$validator" | |
| elif [[ "$EVENT_NAME" == pull_request && "$BASE_REF" == main ]] && \ | |
| [[ -z "$(git rev-list -1 "$TRUSTED_SHA" -- scripts/validate_commits.py)" ]] && \ | |
| git cat-file -e "$HEAD_SHA:scripts/validate_commits.py" 2>/dev/null; then | |
| # Bootstrap only the PR introducing the validator before it has any main history. | |
| git show "$HEAD_SHA:scripts/validate_commits.py" >"$validator" | |
| else | |
| echo "trusted commit validator unavailable at '$TRUSTED_SHA'" >&2 | |
| exit 1 | |
| fi | |
| - name: Validate pull-request title | |
| if: ${{ github.event_name == 'pull_request' }} | |
| env: | |
| PR_TITLE: ${{ github.event.pull_request.title }} | |
| run: python3 "$RUNNER_TEMP/trusted-validator.py" --pr-title "$PR_TITLE" | |
| - name: Validate proposed commit messages | |
| env: | |
| EVENT_NAME: ${{ github.event_name }} | |
| REF_TYPE: ${{ github.ref_type }} | |
| TAG_NAME: ${{ github.ref_name }} | |
| BASE_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event_name == 'push' && github.event.before || '' }} | |
| HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} | |
| run: | | |
| # The merge base selects commits, never executable validation policy. | |
| if [[ "$EVENT_NAME" == push && ( -z "$BASE_SHA" || "$BASE_SHA" =~ ^0+$ ) ]]; then | |
| if [[ "$REF_TYPE" == tag ]]; then | |
| BASE_SHA="$(python3 "$RUNNER_TEMP/trusted-validator.py" --release-base-for "$HEAD_SHA" --exclude-tag "$TAG_NAME")" | |
| if [[ -z "$BASE_SHA" ]]; then | |
| BASE_SHA="$(git merge-base "$HEAD_SHA" origin/main)" | |
| fi | |
| else | |
| BASE_SHA="$(git merge-base "$HEAD_SHA" origin/main)" | |
| fi | |
| fi | |
| python3 "$RUNNER_TEMP/trusted-validator.py" --base "$BASE_SHA" --head "$HEAD_SHA" | |
| - name: Validate release tags are SemVer 2.0.0 | |
| if: ${{ startsWith(github.ref, 'refs/tags/') }} | |
| env: | |
| TAG_NAME: ${{ github.ref_name }} | |
| TAG_COMMIT: ${{ github.sha }} | |
| run: | | |
| # Tag policy uses the same current-main validator loaded above. | |
| validator="$RUNNER_TEMP/trusted-validator.py" | |
| RELEASE_BASE="$(python3 "$validator" --release-base-for "$TAG_COMMIT" --exclude-tag "$TAG_NAME")" | |
| if [[ -n "$RELEASE_BASE" ]]; then | |
| python3 "$validator" --base "$RELEASE_BASE" --head "$TAG_COMMIT" | |
| elif parent=$(git rev-parse "$TAG_COMMIT^" 2>/dev/null); then | |
| python3 "$validator" --base "$parent" --head "$TAG_COMMIT" | |
| else | |
| python3 "$validator" --head "$TAG_COMMIT" | |
| fi | |
| # Stable tags must point into the main line (fetch-depth 0 gives us | |
| # origin/main); prerelease tags must NOT point into it (they are | |
| # branch-local per docs/CONTRIBUTING.md). | |
| python3 "$validator" --version "$TAG_NAME" --tag-commit "$TAG_COMMIT" \ | |
| --base "$RELEASE_BASE" --head "$TAG_COMMIT" --exclude-tag "$TAG_NAME" | |
| validate: | |
| name: Build without registering a runner | |
| needs: commit-convention | |
| if: ${{ !cancelled() && (github.event_name != 'push' || github.event.deleted == false) }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| fetch-depth: 0 | |
| - name: Scan every proposed commit for secrets | |
| env: | |
| EVENT_NAME: ${{ github.event_name }} | |
| REF_TYPE: ${{ github.ref_type }} | |
| TAG_NAME: ${{ github.ref_name }} | |
| BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }} | |
| HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} | |
| run: | | |
| git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main | |
| TRUSTED_SHA="$(git rev-parse origin/main)" | |
| scanner="$RUNNER_TEMP/trusted-secret-scanner.py" | |
| if ! git cat-file -e "$TRUSTED_SHA:scripts/scan_committed_secrets.py" 2>/dev/null; then | |
| echo "trusted secret scanner unavailable at '$TRUSTED_SHA'" >&2 | |
| exit 1 | |
| fi | |
| git show "$TRUSTED_SHA:scripts/scan_committed_secrets.py" >"$scanner" | |
| if [[ "$EVENT_NAME" == push && ( -z "$BASE_SHA" || "$BASE_SHA" =~ ^0+$ ) ]]; then | |
| if [[ "$REF_TYPE" == tag ]]; then | |
| validator="$RUNNER_TEMP/trusted-release-validator.py" | |
| git show "$TRUSTED_SHA:scripts/validate_commits.py" >"$validator" | |
| BASE_SHA="$(python3 "$validator" --release-base-for "$HEAD_SHA" --exclude-tag "$TAG_NAME")" | |
| else | |
| BASE_SHA="$(git merge-base "$HEAD_SHA" origin/main)" | |
| fi | |
| fi | |
| if [[ -z "$BASE_SHA" || "$BASE_SHA" =~ ^0+$ ]]; then | |
| git rev-list --reverse "$HEAD_SHA" >"$RUNNER_TEMP/proposed-commits" | |
| else | |
| if ! git rev-list --reverse "$BASE_SHA..$HEAD_SHA" >"$RUNNER_TEMP/proposed-commits"; then | |
| if [[ "$EVENT_NAME" == push && "$REF_TYPE" == tag ]]; then | |
| # A moved tag's old object may no longer be fetchable. | |
| git rev-list --reverse "$HEAD_SHA" >"$RUNNER_TEMP/proposed-commits" | |
| else | |
| exit 1 | |
| fi | |
| fi | |
| fi | |
| mapfile -t commits <"$RUNNER_TEMP/proposed-commits" | |
| if [[ ! " ${commits[*]} " == *" $HEAD_SHA "* ]]; then | |
| commits+=("$HEAD_SHA") | |
| fi | |
| for commit in "${commits[@]}"; do | |
| python3 "$scanner" --repository "$GITHUB_WORKSPACE" --commit "$commit" | |
| done | |
| - name: Install static analysis tools | |
| run: sudo apt-get update && sudo apt-get install -y shellcheck | |
| - name: Check shell scripts | |
| run: shellcheck scripts/*.sh examples/project/scripts/ci/*.sh templates/config-repository/scripts/*.sh | |
| - name: Check documentation links | |
| run: python3 scripts/check_doc_links.py | |
| - name: Build and inspect inert prototype | |
| run: scripts/validate.sh | |
| - name: Validate public configuration template | |
| run: | | |
| cmp -s scripts/scan_committed_secrets.py templates/config-repository/scripts/scan_committed_secrets.py | |
| python3 templates/config-repository/scripts/test_policy.py | |
| python3 templates/config-repository/scripts/scan_committed_secrets.py | |
| templates/config-repository/scripts/validate.sh | |
| templates/config-repository/scripts/validate.sh --config templates/config-repository/examples/multi-host/fleet.json | |
| temporary_directory="$(mktemp -d)" | |
| if templates/config-repository/scripts/init.sh \ | |
| --organization test-company \ | |
| --project test-app \ | |
| --output "${temporary_directory}/missing-engine.json"; then | |
| echo 'initializer accepted a missing engine revision' >&2 | |
| exit 1 | |
| fi | |
| test ! -e "${temporary_directory}/missing-engine.json" | |
| if templates/config-repository/scripts/init.sh \ | |
| --organization test-company \ | |
| --project test-app \ | |
| --registry BAD \ | |
| --engine-ref "$(git rev-parse HEAD)" \ | |
| --output "${temporary_directory}/invalid.json"; then | |
| echo 'initializer accepted an invalid registry' >&2 | |
| exit 1 | |
| fi | |
| test ! -e "${temporary_directory}/invalid.json" | |
| templates/config-repository/scripts/init.sh \ | |
| --organization test-company \ | |
| --project test-app \ | |
| --engine-ref "$(git rev-parse HEAD)" \ | |
| --output "${temporary_directory}/fleet.json" | |
| test "$(stat -c '%a' "${temporary_directory}/fleet.json")" = 644 | |
| - name: Require successful convention validation | |
| env: | |
| CONVENTION_RESULT: ${{ needs.commit-convention.result }} | |
| run: | | |
| test "$CONVENTION_RESULT" = success |