aquasecurity/trivy

22 workflows · maturity 50% · 7 patterns · GitHub ↗

Security 28.33/100

Practices

✓ Matrix○ Permissions✓ Security scan○ AI review✓ Cache○ Concurrency✓ Reusable workflows

Detected patterns

Security dimensions

permissions
0
security scan
8.3
supply chain
20
secret handling
0
harden runner
0

Tools: ./.github/actions/trivy-triage, knqyf263/trivy-issue-action

Workflows (22)

auto-close-issue .github/workflows/auto-close-issue.yaml
Triggers
issues
Runs on
ubuntu-latest
Jobs
close_issue
View raw YAML
name: Auto-close issues

on:
  issues:
    types: [opened]

jobs:
  close_issue:
    runs-on: ubuntu-latest
    steps:
      - name: Close issue if user does not have write or admin permissions
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
        with:
          script: |
            // Get the issue creator's username
            const issueCreator = context.payload.issue.user.login;
            
            // Check the user's permissions for the repository
            const repoPermissions = await github.rest.repos.getCollaboratorPermissionLevel({
              owner: context.repo.owner,
              repo: context.repo.repo,
              username: issueCreator
            });
            
            const permission = repoPermissions.data.permission;
            
            // If the user does not have write or admin permissions, leave a comment and close the issue
            if (permission !== 'write' && permission !== 'admin') {
              const commentBody = "Please see https://trivy.dev/docs/latest/community/contribute/issue/";
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: context.payload.issue.number,
                body: commentBody
              });
            
              await github.rest.issues.update({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: context.payload.issue.number,
                state: 'closed',
                state_reason: 'not_planned'
              });
            
              console.log(`Issue #${context.payload.issue.number} closed because ${issueCreator} does not have sufficient permissions.`);
            }
auto-ready-for-review .github/workflows/auto-ready-for-review.yaml
Triggers
workflow_run
Runs on
ubuntu-24.04
Jobs
auto-ready-for-review
Commands
  • echo "[INFO] Searching for PR with branch: ${PR_BRANCH}" if gh pr view --repo "${{ github.repository }}" "${PR_BRANCH}" --json 'number' --jq '"number=\(.number)"' >> "${GITHUB_OUTPUT}"; then echo "[INFO] PR found successfully" else echo "[INFO] No PR found for branch ${PR_BRANCH}, skipping" echo "skip=true" >> "${GITHUB_OUTPUT}" fi
View raw YAML
name: Auto Ready for Review

on:
  # workflow_run runs in the context of the base repo with full permissions, but this workflow
  # does not check out any PR code — it only reads PR metadata via the GitHub API and marks
  # the PR as ready for review. No code execution from forks occurs.
  workflow_run: # zizmor: ignore[dangerous-triggers]
    workflows: ["Test", "Validate PR Title"]
    types: [completed]

jobs:
  auto-ready-for-review:
    runs-on: ubuntu-24.04
    if: github.event.workflow_run.event == 'pull_request'
    steps:
      - name: Get PR context
        id: pr-context
        env:
          GH_TOKEN: ${{ github.token }}
          PR_BRANCH: |-
            ${{
              (github.event.workflow_run.head_repository.owner.login != github.event.workflow_run.repository.owner.login)
                && format('{0}:{1}', github.event.workflow_run.head_repository.owner.login, github.event.workflow_run.head_branch)
                || github.event.workflow_run.head_branch
            }}
        run: |
          echo "[INFO] Searching for PR with branch: ${PR_BRANCH}"
          if gh pr view --repo "${{ github.repository }}" "${PR_BRANCH}" --json 'number' --jq '"number=\(.number)"' >> "${GITHUB_OUTPUT}"; then
            echo "[INFO] PR found successfully"
          else
            echo "[INFO] No PR found for branch ${PR_BRANCH}, skipping"
            echo "skip=true" >> "${GITHUB_OUTPUT}"
          fi
          
      - name: Check PR and all workflows status
        if: steps.pr-context.outputs.skip != 'true'
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
        env:
          PR_NUMBER: ${{ steps.pr-context.outputs.number }}
        with:
          script: |
            const prNumber = parseInt(process.env.PR_NUMBER, 10);
            console.log(`[INFO] Processing PR #${prNumber}`);
            
            // Get PR info
            const { data: pr } = await github.rest.pulls.get({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: prNumber
            });
            
            console.log(`[INFO] PR #${prNumber} - Draft: ${pr.draft}, Labels: ${pr.labels.map(l => l.name).join(', ')}`);
            
            // Check if PR has autoready label and is draft
            const hasAutoreadyLabel = pr.labels.some(label => label.name === 'autoready');
            
            if (!pr.draft) {
              console.log(`[INFO] PR #${prNumber} is not draft, skipping`);
              return;
            }
            
            if (!hasAutoreadyLabel) {
              console.log(`[INFO] PR #${prNumber} doesn't have autoready label, skipping`);
              return;
            }
            
            // Get all workflow runs for this PR's head commit (head_sha)
            const { data: workflowRuns } = await github.rest.actions.listWorkflowRunsForRepo({
              owner: context.repo.owner,
              repo: context.repo.repo,
              head_sha: pr.head.sha,
              per_page: 100
            });
            
            console.log(`[INFO] Found ${workflowRuns.workflow_runs.length} workflow runs for PR #${prNumber}`);
            
            // Check workflow status
            const runningWorkflows = workflowRuns.workflow_runs.filter(run => 
              run.status === 'in_progress' || run.status === 'queued'
            );
            
            const failedWorkflows = workflowRuns.workflow_runs.filter(run => 
              run.conclusion === 'failure' || run.conclusion === 'cancelled'
            );
            
            const successfulWorkflows = workflowRuns.workflow_runs.filter(run => 
              run.conclusion === 'success'
            );
            
            console.log(`[INFO] Workflow status - Running: ${runningWorkflows.length}, Failed: ${failedWorkflows.length}, Success: ${successfulWorkflows.length}`);
            
            if (runningWorkflows.length > 0) {
              console.log(`[INFO] Some workflows are still running: ${runningWorkflows.map(w => w.name).join(', ')}`);
              return;
            }
            
            if (failedWorkflows.length > 0) {
              console.log(`[INFO] Some workflows failed: ${failedWorkflows.map(w => w.name).join(', ')}`);
              return;
            }
            
            console.log(`[INFO] All workflows passed! Marking PR #${prNumber} as ready for review...`);
            
            // Mark PR as ready for review using GraphQL API
            // Reference: https://github.com/orgs/community/discussions/70061
            try {
              const mutation = `
                mutation MarkPullRequestReadyForReview($pullRequestId: ID!) {
                  markPullRequestReadyForReview(input: { pullRequestId: $pullRequestId }) {
                    pullRequest {
                      id
                      isDraft
                      number
                    }
                  }
                }
              `;
              
              const updateResult = await github.graphql(mutation, {
                pullRequestId: pr.node_id
              });
              
              const isDraft = updateResult.markPullRequestReadyForReview.pullRequest.isDraft;
              console.log(`[SUCCESS] PR #${prNumber} marked as ready for review. Draft status: ${isDraft}`);
            } catch (error) {
              console.log(`[ERROR] Failed to mark PR #${prNumber} as ready for review: ${error.message}`);
              console.log(`[ERROR] Error details: ${JSON.stringify(error.response?.data || error, null, 2)}`);
              return;
            }
            
            // Remove autoready label
            try {
              const labelResult = await github.rest.issues.removeLabel({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: prNumber,
                name: 'autoready'
              });
              console.log(`[SUCCESS] autoready label removed from PR #${prNumber}. Status: ${labelResult.status}`);
            } catch (error) {
              console.log(`[WARNING] Could not remove autoready label from PR #${prNumber}: ${error.message}`);
              console.log(`[WARNING] Error details: ${JSON.stringify(error.response?.data || error, null, 2)}`);
            }
auto-update-labels .github/workflows/auto-update-labels.yaml
Triggers
push
Runs on
ubuntu-latest
Jobs
deploy
Commands
  • go install tool
  • mage label
View raw YAML
name: Auto-update labels
on:
  push:
    paths:
      - 'misc/triage/labels.yaml'
    branches:
      - main
jobs:
  deploy:
    name: Auto-update labels
    runs-on: ubuntu-latest
    steps:
      - name: Checkout main
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Set up Go
        uses: ./.github/actions/setup-go

      - name: Install Go tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: update labels
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: mage label
backport .github/workflows/backport.yaml
Triggers
issue_comment
Runs on
ubuntu-latest, ubuntu-latest
Jobs
check_permission, backport
Commands
  • PERMISSION=$(gh api /repos/$GITHUB_REPOSITORY/collaborators/$GITHUB_ACTOR/permission --jq '.permission') if [ "$PERMISSION" == "admin" ] || [ "$PERMISSION" == "write" ]; then echo "is_maintainer=true" >> $GITHUB_OUTPUT else echo "is_maintainer=false" >> $GITHUB_OUTPUT fi
  • BRANCH_NAME=$(echo "$COMMENT_BODY" | grep -oE '@aqua-bot backport\s+(\S+)' | awk '{print $3}') if [[ -z "$BRANCH_NAME" || "$BRANCH_NAME" == *".."* || ! "$BRANCH_NAME" =~ ^[A-Za-z0-9._-]+(/[A-Za-z0-9._-]+)*$ ]]; then echo "Error: Invalid branch name extracted (unsafe characters detected)." >&2 exit 1 fi echo "BRANCH_NAME=$BRANCH_NAME" >> "$GITHUB_ENV"
  • git config --global user.email "actions@github.com" git config --global user.name "GitHub Actions"
  • ./misc/backport/backport.sh "$BRANCH_NAME" "$ISSUE_NUMBER"
View raw YAML
name: Automatic Backporting

on:
  issue_comment:
    types: [created]

jobs:
  check_permission:
    name: Check comment author permissions
    runs-on: ubuntu-latest
    outputs:
      is_maintainer: ${{ steps.check_permission.outputs.is_maintainer }}
    steps:
      - name: Check permission
        id: check_permission
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          PERMISSION=$(gh api /repos/$GITHUB_REPOSITORY/collaborators/$GITHUB_ACTOR/permission --jq '.permission')
          if [ "$PERMISSION" == "admin" ] || [ "$PERMISSION" == "write" ]; then
           echo "is_maintainer=true" >> $GITHUB_OUTPUT
          else
           echo "is_maintainer=false" >> $GITHUB_OUTPUT
          fi
  

  backport:
    name: Backport PR
    needs: check_permission # run this job after checking permissions
    if: |
      needs.check_permission.outputs.is_maintainer == 'true' &&      
      github.event.issue.pull_request &&
      github.event.issue.pull_request.merged_at != null &&
      startsWith(github.event.comment.body, '@aqua-bot backport release/')
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          fetch-depth: 0
          persist-credentials: true # backport.sh runs git push

      - name: Extract branch name
        env:
          COMMENT_BODY: ${{ github.event.comment.body }}
        run: |
          BRANCH_NAME=$(echo "$COMMENT_BODY" | grep -oE '@aqua-bot backport\s+(\S+)' | awk '{print $3}')
          if [[ -z "$BRANCH_NAME" || "$BRANCH_NAME" == *".."* || ! "$BRANCH_NAME" =~ ^[A-Za-z0-9._-]+(/[A-Za-z0-9._-]+)*$ ]]; then
            echo "Error: Invalid branch name extracted (unsafe characters detected)." >&2
            exit 1
          fi
          echo "BRANCH_NAME=$BRANCH_NAME" >> "$GITHUB_ENV"

      - name: Set up Git user
        run: |
          git config --global user.email "actions@github.com"
          git config --global user.name "GitHub Actions"

      - name: Run backport script
        env:
          # Use ORG_REPO_TOKEN instead of GITHUB_TOKEN
          # This allows the created PR to trigger tests and other workflows
          GITHUB_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}
          ISSUE_NUMBER: ${{ github.event.issue.number }}
        run: ./misc/backport/backport.sh "$BRANCH_NAME" "$ISSUE_NUMBER"
bypass-cla .github/workflows/bypass-cla.yaml
Triggers
merge_group
Runs on
ubuntu-latest
Jobs
cla
Commands
  • echo "No test required"
View raw YAML
# This workflow is used to bypass the required status checks in merge queue.
# cf. https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/troubleshooting-required-status-checks
name: CLA
on:
  merge_group:

jobs:
  cla:
    name: license/cla
    runs-on: ubuntu-latest
    steps:
      - run: 'echo "No test required"'
bypass-test matrix .github/workflows/bypass-test.yaml
Triggers
push, pull_request
Runs on
${{ matrix.operating-system }}, ubuntu-latest
Jobs
test, integration
Matrix
operating-system→ macos-latest, ubuntu-latest, windows-latest
Commands
  • echo "No test required"
  • echo "No test required"
View raw YAML
# This workflow is used to bypass the required status checks.
# cf. https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/troubleshooting-required-status-checks
name: Test
on:
  push:
    paths:
      - '**.md'
      - 'docs/**'
      - 'mkdocs.yml'
      - 'LICENSE'
      - '.release-please-manifest.json'
      - 'helm/trivy/Chart.yaml'
  pull_request:
    paths:
      - '**.md'
      - 'docs/**'
      - 'mkdocs.yml'
      - 'LICENSE'
      - '.release-please-manifest.json'
      - 'helm/trivy/Chart.yaml'
jobs:
  test:
    name: Test
    runs-on: ${{ matrix.operating-system }}
    strategy:
      matrix:
        operating-system: [ubuntu-latest, windows-latest, macos-latest]
    steps:
      - run: 'echo "No test required"'

  integration:
    name: Integration Test
    runs-on: ubuntu-latest
    steps:
      - run: 'echo "No test required"'
cache-test-assets .github/workflows/cache-test-assets.yaml
Triggers
push, workflow_dispatch
Runs on
ubuntu-latest, ubuntu-latest, ubuntu-latest
Jobs
test-images, test-vm-images, lint-cache
Actions
golangci/golangci-lint-action
Commands
  • go install tool
  • source integration/testimages.ini IMAGE_LIST=$(skopeo list-tags docker://$TEST_IMAGES) DIGEST=$(echo "$IMAGE_LIST" | jq '.Tags += ["containerd"] | .Tags |= sort' | sha256sum | cut -d' ' -f1) echo "digest=$DIGEST" >> $GITHUB_OUTPUT
  • mage test:fixtureContainerImages
  • go install tool
  • source integration/testimages.ini IMAGE_LIST=$(skopeo list-tags docker://$TEST_VM_IMAGES) DIGEST=$(echo "$IMAGE_LIST" | jq '.Tags |= sort' | sha256sum | cut -d' ' -f1) echo "digest=$DIGEST" >> $GITHUB_OUTPUT
  • mage test:fixtureVMImages
View raw YAML
name: Cache test assets
# This workflow runs on the main branch to create caches that can be accessed by PRs.
# GitHub Actions cache isolation restricts access:
# - PRs can only restore caches from: current branch, base branch, and default branch (main)
# - PRs cannot restore caches from sibling branches or other PR branches
# - By creating caches on the main branch, all PRs can benefit from shared cache
on:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  test-images:
    name: Cache test images
    runs-on: ubuntu-latest
    steps:
      - name: Check out code into the Go module directory
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Set up Go
        uses: ./.github/actions/setup-go

      - name: Install Go tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Generate image list digest
        id: image-digest
        run: |
          source integration/testimages.ini
          IMAGE_LIST=$(skopeo list-tags docker://$TEST_IMAGES)
          DIGEST=$(echo "$IMAGE_LIST" | jq '.Tags += ["containerd"] | .Tags |= sort' | sha256sum | cut -d' ' -f1)
          echo "digest=$DIGEST" >> $GITHUB_OUTPUT

      - name: Restore and save test images cache
        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
        with:
          path: integration/testdata/fixtures/images
          key: cache-test-images-${{ steps.image-digest.outputs.digest }}

      - name: Download test images
        run: mage test:fixtureContainerImages

  test-vm-images:
    name: Cache test VM images
    runs-on: ubuntu-latest
    steps:
      - name: Check out code into the Go module directory
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Set up Go
        uses: ./.github/actions/setup-go

      - name: Install Go tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Generate image list digest
        id: image-digest
        run: |
          source integration/testimages.ini
          IMAGE_LIST=$(skopeo list-tags docker://$TEST_VM_IMAGES)
          DIGEST=$(echo "$IMAGE_LIST" | jq '.Tags |= sort' | sha256sum | cut -d' ' -f1)
          echo "digest=$DIGEST" >> $GITHUB_OUTPUT

      - name: Restore and save test VM images cache
        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
        with:
          path: integration/testdata/fixtures/vm-images
          key: cache-test-vm-images-${{ steps.image-digest.outputs.digest }}

      - name: Download test VM images
        run: mage test:fixtureVMImages

  lint-cache:
    name: Cache lint results
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Set up Go
        uses: ./.github/actions/setup-go

      - name: Run golangci-lint for caching
        uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
        with:
          version: v2.10
          args: --verbose
        env:
          GOEXPERIMENT: jsonv2
canary .github/workflows/canary.yaml
Triggers
push, workflow_dispatch
Runs on
ubuntu-latest
Jobs
build-binaries, upload-binaries
Commands
  • gh cache delete "$CACHE_KEY" --repo "${{ github.repository }}"
View raw YAML
name: Canary build
on:
  push:
    branches:
      - 'main'
    paths:
      - '**.go'
      - 'go.mod'
      - 'Dockerfile.canary'
      - '.github/workflows/canary.yaml'
  workflow_dispatch:

jobs:
  build-binaries:
    name: Build binaries
    uses: ./.github/workflows/reusable-release.yaml
    with:
      goreleaser_config: goreleaser-canary.yml
      goreleaser_options: '--snapshot --clean --timeout 60m' # will not release
    secrets:
      DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
      DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
      ECR_ACCESS_KEY_ID: ${{ secrets.ECR_ACCESS_KEY_ID }}
      ECR_SECRET_ACCESS_KEY: ${{ secrets.ECR_SECRET_ACCESS_KEY }}
      GPG_KEY: ${{ secrets.GPG_KEY }}
      ORG_REPO_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}
      GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}

  upload-binaries:
    name: Upload binaries
    needs: build-binaries # run this job after 'build-binaries' job completes
    runs-on: ubuntu-latest
    steps:
      - name: Restore Trivy binaries from cache
        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
        with:
          path: dist/
          key: ${{ runner.os }}-bins-${{ github.workflow }}-${{ github.sha }}

        # Upload artifacts
      - name: Upload artifacts (trivy_Linux-64bit)
        uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
        with:
          name: trivy_Linux-64bit
          path: dist/trivy_*_Linux-64bit.tar.gz
          if-no-files-found: error

      - name: Upload artifacts (trivy_Linux-ARM64)
        uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
        with:
          name: trivy_Linux-ARM64
          path: dist/trivy_*_Linux-ARM64.tar.gz
          if-no-files-found: error

      - name: Upload artifacts (trivy_macOS-64bit)
        uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
        with:
          name: trivy_macOS-64bit
          path: dist/trivy_*_macOS-64bit.tar.gz
          if-no-files-found: error

      - name: Upload artifacts (trivy_macOS-ARM64)
        uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
        with:
          name: trivy_macOS-ARM64
          path: dist/trivy_*_macOS-ARM64.tar.gz
          if-no-files-found: error

      - name: Delete cache after upload
        run: |
          gh cache delete "$CACHE_KEY" --repo "${{ github.repository }}"
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          CACHE_KEY: ${{ runner.os }}-bins-${{ github.workflow }}-${{ github.sha }}
mkdocs-dev .github/workflows/mkdocs-dev.yaml
Triggers
push
Runs on
ubuntu-22.04
Jobs
deploy
Commands
  • python -m pip install --upgrade pip setuptools wheel pip install git+https://${GH_TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git@9.5.44-insiders-4.53.14 pip install -r docs/build/requirements.txt
  • git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
  • mike deploy --push dev
View raw YAML
name: Deploy the dev documentation
on:
  push:
    paths:
      - 'docs/**'
      - mkdocs.yml
    branches:
      - main
jobs:
  deploy:
    name: Deploy the dev documentation
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout main
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          fetch-depth: 0
          persist-credentials: true
      - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
        with:
          python-version: 3.x
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip setuptools wheel
          pip install git+https://${GH_TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git@9.5.44-insiders-4.53.14
          pip install -r docs/build/requirements.txt
        env:
          GH_TOKEN: ${{ secrets.MKDOCS_AQUA_BOT }}
      - name: Configure the git user
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
      - name: Deploy the dev documents
        run: mike deploy --push dev
mkdocs-latest .github/workflows/mkdocs-latest.yaml
Triggers
workflow_dispatch, push
Runs on
ubuntu-22.04, ubuntu-22.04
Jobs
deploy, trigger-trivy-www-deploy
Commands
  • python -m pip install --upgrade pip setuptools wheel pip install git+https://${GH_TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git@9.5.44-insiders-4.53.14 pip install -r docs/build/requirements.txt
  • git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
  • VERSION=$(echo "$GITHUB_REF" | sed -e "s#refs/tags/##g") mike deploy --push --update-aliases ${VERSION%.*} latest
  • mike deploy --push --update-aliases "$DOCS_VERSION" latest
  • gh workflow run build-docs.yml \ --repo "$GITHUB_REPOSITORY_OWNER/trivy-www" \ --ref main \ --field "from_version=$GITHUB_REF_NAME"
View raw YAML
name: Deploy the latest documentation
on:
  workflow_dispatch:
    inputs:
      version:
        description: Version to be deployed
        required: true
  push:
    tags:
      - "v*"
jobs:
  deploy:
    name: Deploy the latest documentation
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout main
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          fetch-depth: 0
          persist-credentials: true
      - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
        with:
          python-version: 3.x
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip setuptools wheel
          pip install git+https://${GH_TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git@9.5.44-insiders-4.53.14
          pip install -r docs/build/requirements.txt
        env:
          GH_TOKEN: ${{ secrets.MKDOCS_AQUA_BOT }}
      - name: Configure the git user
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
      - name: Deploy the latest documents from new tag push
        if: ${{ github.event.inputs.version == '' }}
        run: |
          VERSION=$(echo "$GITHUB_REF" | sed -e "s#refs/tags/##g")
          mike deploy --push --update-aliases ${VERSION%.*} latest
      - name: Deploy the latest documents from manual trigger
        if: ${{ github.event.inputs.version != '' }}
        env:
          DOCS_VERSION: ${{ github.event.inputs.version }}
        run: mike deploy --push --update-aliases "$DOCS_VERSION" latest

  # This workflow is used to trigger the trivy-www deployment
  trigger-trivy-www-deploy: 
    needs: deploy
    runs-on: ubuntu-22.04
    steps:
      - name: Trigger update_version workflow in trivy-telemetry
        env:
          # Use ORG_REPO_TOKEN instead of GITHUB_TOKEN
          # This allows triggering workflows in other repositories
          GH_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}
        run: |
          gh workflow run build-docs.yml \
            --repo "$GITHUB_REPOSITORY_OWNER/trivy-www" \
            --ref main \
            --field "from_version=$GITHUB_REF_NAME"
publish-chart .github/workflows/publish-chart.yaml
Triggers
workflow_dispatch, pull_request
Runs on
ubuntu-24.04, ubuntu-24.04
Jobs
test-chart, publish-chart
Actions
azure/setup-helm, helm/chart-testing-action, helm/kind-action, dmnemec/copy_file_to_another_repo_action
Commands
  • ct lint-and-install --validate-maintainers=false --charts helm/trivy
  • sed -i -e '136s,false,'true',g' ./helm/trivy/values.yaml ct lint-and-install --validate-maintainers=false --charts helm/trivy
  • wget https://github.com/helm/chart-releaser/releases/download/v1.3.0/chart-releaser_1.3.0_linux_amd64.tar.gz echo "baed2315a9bb799efb71d512c5198a2a3b8dcd139d7f22f878777cffcd649a37 chart-releaser_1.3.0_linux_amd64.tar.gz" | sha256sum -c - tar xzvf chart-releaser_1.3.0_linux_amd64.tar.gz cr
  • ./cr package ${{ env.CHART_DIR }}
  • ./cr upload -o ${{ env.GH_OWNER }} -r ${{ env.HELM_REP }} --token ${{ secrets.ORG_REPO_TOKEN }} -p .cr-release-packages
  • ./cr index -o ${{ env.GH_OWNER }} -r ${{ env.HELM_REP }} -c https://${{ env.GH_OWNER }}.github.io/${{ env.HELM_REP }}/ -i index.yaml
View raw YAML
name: Publish Helm chart

on:
  workflow_dispatch:
  pull_request:
    types:
      - opened
      - synchronize
      - reopened
      - closed
    branches:
      - main
    paths:
      - 'helm/trivy/**'
env:
  HELM_REP: helm-charts
  GH_OWNER: aquasecurity
  CHART_DIR: helm/trivy
  KIND_VERSION: "v0.14.0"
  KIND_IMAGE: "kindest/node:v1.23.6@sha256:b1fa224cc6c7ff32455e0b1fd9cbfd3d3bc87ecaa8fcb06961ed1afb3db0f9ae"
jobs:
  # `test-chart` job starts if a PR with Helm Chart is created, merged etc.
  test-chart:
    runs-on: ubuntu-24.04
    steps:
      - name: Checkout
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          fetch-depth: 0
          persist-credentials: false
      - name: Install Helm
        uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
        with:
          version: v3.14.4
      - name: Set up python
        uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
        with:
          python-version: '3.x'
          check-latest: true
      - name: Setup Chart Linting
        id: lint
        uses: helm/chart-testing-action@6ec842c01de15ebb84c8627d2744a0c2f2755c9f # v2.8.0
        with:
          # v6.0.0 resolved the compatibility issue with Python > 3.13. may be removed after the action itself is updated
          yamale_version: "6.0.0"
      - name: Setup Kubernetes cluster (KIND)
        uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0
        with:
          version: ${{ env.KIND_VERSION }}
          image: ${{ env.KIND_IMAGE }}
      - name: Run chart-testing
        run: ct lint-and-install --validate-maintainers=false --charts helm/trivy
      - name: Run chart-testing (Ingress enabled)
        run: |
          sed -i -e '136s,false,'true',g' ./helm/trivy/values.yaml
          ct lint-and-install --validate-maintainers=false --charts helm/trivy


  # `publish-chart` job starts if a PR with a new Helm Chart is merged or manually
  publish-chart:
    if: github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch'
    needs:
      - test-chart
    runs-on: ubuntu-24.04
    steps:
      - name: Checkout
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          fetch-depth: 0
          persist-credentials: false
      - name: Install chart-releaser
        run: |
          wget https://github.com/helm/chart-releaser/releases/download/v1.3.0/chart-releaser_1.3.0_linux_amd64.tar.gz
          echo "baed2315a9bb799efb71d512c5198a2a3b8dcd139d7f22f878777cffcd649a37  chart-releaser_1.3.0_linux_amd64.tar.gz" | sha256sum -c -
          tar xzvf chart-releaser_1.3.0_linux_amd64.tar.gz cr
      - name: Package helm chart
        run: |
          ./cr package ${{ env.CHART_DIR }}
      - name: Upload helm chart
        # Failed with upload the same version: https://github.com/helm/chart-releaser/issues/101
        continue-on-error: true
        run: |
          ./cr upload -o ${{ env.GH_OWNER }} -r ${{ env.HELM_REP }} --token ${{ secrets.ORG_REPO_TOKEN }} -p .cr-release-packages
      - name: Index helm chart
        run: |
          ./cr index -o ${{ env.GH_OWNER }} -r ${{ env.HELM_REP }} -c https://${{ env.GH_OWNER }}.github.io/${{ env.HELM_REP }}/ -i index.yaml
      - name: Push index file
        uses: dmnemec/copy_file_to_another_repo_action@c93037aa10fa8893de271f19978c980d0c1a9b37 #v1.1.1
        env:
          API_TOKEN_GITHUB: ${{ secrets.ORG_REPO_TOKEN }}
        with:
          source_file: 'index.yaml'
          destination_repo: '${{ env.GH_OWNER }}/${{ env.HELM_REP }}'
          destination_folder: '.'
          destination_branch: 'gh-pages'
          user_email: aqua-bot@users.noreply.github.com
          user_name: 'aqua-bot'
release .github/workflows/release.yaml
Triggers
push
Runs on
ubuntu-22.04, ubuntu-22.04, ubuntu-22.04
Jobs
release, deploy-packages, update-chart-version, trigger-version-update
Commands
  • sudo apt-get -y update sudo apt-get -y install rpm reprepro createrepo-c distro-info
  • git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" git config --global user.name "github-actions[bot]"
  • ci/deploy-rpm.sh
  • echo -e "${{ secrets.GPG_KEY }}" | gpg --import
  • ci/deploy-deb.sh
  • git config --global user.email "actions@github.com" git config --global user.name "GitHub Actions"
  • go install tool
  • mage helm:updateVersion
View raw YAML
name: Release
on:
  push:
    tags:
      - "v*"

jobs:
  release:
    name: Release
    uses: ./.github/workflows/reusable-release.yaml
    with:
      goreleaser_config: goreleaser.yml
      goreleaser_options: '--clean --timeout 90m'
    secrets:
      DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
      DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
      ECR_ACCESS_KEY_ID: ${{ secrets.ECR_ACCESS_KEY_ID }}
      ECR_SECRET_ACCESS_KEY: ${{ secrets.ECR_SECRET_ACCESS_KEY }}
      GPG_KEY: ${{ secrets.GPG_KEY }}
      ORG_REPO_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}
      GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}

  deploy-packages:
    name: Deploy rpm/dep packages
    needs: release # run this job after 'release' job completes
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          fetch-depth: 0
          persist-credentials: false

      # Cache is keyed by github.sha and scoped to tag-push events triggered by maintainers only.
      # Cache is written exclusively by the release job (reusable-release.yaml) on the same
      # tag-push event. Only maintainers can push tags, so external contributors cannot influence
      # the cache contents. The key includes github.sha to prevent collisions across runs.
      - name: Restore Trivy binaries from cache
        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 # zizmor: ignore[cache-poisoning]
        with:
          path: dist/
          key: ${{ runner.os }}-bins-${{github.workflow}}-${{github.sha}}

      - name: Install dependencies
        run: |
          sudo apt-get -y update
          sudo apt-get -y install rpm reprepro createrepo-c distro-info

      - name: Checkout trivy-repo
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          repository: ${{ github.repository_owner }}/trivy-repo
          path: trivy-repo
          token: ${{ secrets.ORG_REPO_TOKEN }}
          persist-credentials: true # deploy-rpm.sh and deploy-deb.sh run git push

      - name: Setup git settings
        run: |
          git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git config --global user.name "github-actions[bot]"

      - name: Create rpm repository
        run: ci/deploy-rpm.sh

      - name: Import GPG key
        run: echo -e "${{ secrets.GPG_KEY }}" | gpg --import

      - name: Create deb repository
        run: ci/deploy-deb.sh

  # `update-chart-version` creates a new PR for updating the helm chart
  update-chart-version:
    needs: deploy-packages
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          fetch-depth: 0
          persist-credentials: true # mage helm:updateVersion runs git push

      - name: Set up Git user
        run: |
          git config --global user.email "actions@github.com"
          git config --global user.name "GitHub Actions"

      - name: Set up Go
        uses: ./.github/actions/setup-go

      - name: Install Go tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Create a PR with Trivy version
        run: mage helm:updateVersion
        env:
          # Use ORG_REPO_TOKEN instead of GITHUB_TOKEN
          # This allows the created PR to trigger tests and other workflows
          GITHUB_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}

  # `trigger-version-update` triggers workflows in the `aqua` repositories to update the Trivy version.
  trigger-version-update:
    needs: deploy-packages
    runs-on: ubuntu-22.04
    steps:
      - name: Trigger update_version workflow in trivy-telemetry
        if: always()
        env:
          # Use ORG_REPO_TOKEN instead of GITHUB_TOKEN
          # This allows triggering workflows in other repositories
          GH_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}
        run: |
          gh workflow run update_version.yml \
            --repo "$GITHUB_REPOSITORY_OWNER/trivy-telemetry" \
            --ref main \
            --field "version=$GITHUB_REF_NAME"

      - name: Trigger update_version workflow in trivy-downloads
        if: always()
        env:
          # Use ORG_REPO_TOKEN instead of GITHUB_TOKEN
          # This allows triggering workflows in other repositories
          GH_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}
        run: |
          gh workflow run update_version.yml \
            --repo "$GITHUB_REPOSITORY_OWNER/trivy-downloads" \
            --ref main \
            --field "version=$GITHUB_REF_NAME" \
            --field artifact=trivy

      - name: Trigger version update and release workflow in trivy-chocolatey
        if: always()
        env:
          # Use ORG_REPO_TOKEN instead of GITHUB_TOKEN
          # This allows triggering workflows in other repositories
          GH_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}
        run: |
          gh workflow run release.yml \
            --repo "$GITHUB_REPOSITORY_OWNER/trivy-chocolatey" \
            --ref main \
            --field "version=$GITHUB_REF_NAME"

      - name: Run version bump in trivy-action
        if: always()
        env:
          # Use ORG_REPO_TOKEN instead of GITHUB_TOKEN
          # This allows triggering workflows in other repositories
          GH_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}
        run: |
          VERSION="${GITHUB_REF_NAME#v}"
          gh workflow run bump-trivy.yaml \
            --repo "$GITHUB_REPOSITORY_OWNER/trivy-action" \
            --ref master \
            --field "trivy_version=$VERSION"
release-please .github/workflows/release-please.yaml
Triggers
push, workflow_dispatch
Runs on
ubuntu-latest, ubuntu-latest, ubuntu-latest
Jobs
release-please, manual-release-please, release-tag
Actions
googleapis/release-please-action
Commands
  • npm install release-please -g
  • release-please release-pr --repo-url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" \ --token="${{ secrets.ORG_REPO_TOKEN }}" \ --release-as="$RELEASE_VERSION" \ --target-branch="$GITHUB_REF_NAME"
  • echo "version=$( echo "$COMMIT_MESSAGE" | sed 's/^release: v\([0-9]\+\.[0-9]\+\.[0-9]\+\).*$/\1/' )" >> $GITHUB_OUTPUT echo "pr_number=$( echo "$COMMIT_MESSAGE" | sed 's/.*(\#\([0-9]\+\)).*$/\1/' )" >> $GITHUB_OUTPUT echo "release_branch=release/v$( echo "$COMMIT_MESSAGE" | sed 's/^release: v\([0-9]\+\.[0-9]\+\).*$/\1/' )" >> $GITHUB_OUTPUT
  • RULESET_ID=$(gh api /repos/${GITHUB_REPOSITORY}/rulesets --jq '.[] | select(.name=="release") | .id') gh api /repos/${GITHUB_REPOSITORY}/rulesets/$RULESET_ID | jq '{conditions}' | jq ".conditions.ref_name.include += [\"refs/heads/${RELEASE_BRANCH}\"]" | gh api --method put --input - /repos/${GITHUB_REPOSITORY}/rulesets/$RULESET_ID
View raw YAML
name: Release Please

on:
  push:
    branches:
      - main
      - 'release/v*'
  workflow_dispatch:
    inputs:
      version:
        required: true
        description: 'Release version without the "v" prefix (e.g., 0.51.0)'
        type: string

jobs:
  release-please:
    runs-on: ubuntu-latest
    if: ${{ !startsWith(github.event.head_commit.message, 'release:') && !github.event.inputs.version }}
    steps:
      - name: Release Please
        id: release
        uses: googleapis/release-please-action@16a9c90856f42705d54a6fda1823352bdc62cf38 # v4.4.0
        with:
          token: ${{ secrets.ORG_REPO_TOKEN }}
          target-branch: ${{ github.ref_name }}

  manual-release-please:
    runs-on: ubuntu-latest
    if: ${{ github.event.inputs.version }}
    steps:
      - name: Install Release Please CLI
        run: npm install release-please -g

      - name: Release Please
        env:
          RELEASE_VERSION: ${{ github.event.inputs.version }}
        run: |
          release-please release-pr --repo-url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" \
            --token="${{ secrets.ORG_REPO_TOKEN }}" \
            --release-as="$RELEASE_VERSION" \
            --target-branch="$GITHUB_REF_NAME"

  release-tag:
    runs-on: ubuntu-latest
    if: ${{ startsWith(github.event.head_commit.message, 'release:') }}
    steps:
      # Since skip-github-release is specified, the outputs of googleapis/release-please-action cannot be used.
      # Therefore, we need to parse the version ourselves.
      - name: Extract version and PR number from commit message
        id: extract_info
        shell: bash
        env:
          COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
        run: |
          echo "version=$( echo "$COMMIT_MESSAGE" | sed 's/^release: v\([0-9]\+\.[0-9]\+\.[0-9]\+\).*$/\1/' )" >> $GITHUB_OUTPUT
          echo "pr_number=$( echo "$COMMIT_MESSAGE" | sed 's/.*(\#\([0-9]\+\)).*$/\1/' )" >> $GITHUB_OUTPUT
          echo "release_branch=release/v$( echo "$COMMIT_MESSAGE" | sed 's/^release: v\([0-9]\+\.[0-9]\+\).*$/\1/' )" >> $GITHUB_OUTPUT

      - name: Tag release
        if: ${{ steps.extract_info.outputs.version }}
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
        env:
          VERSION: ${{ steps.extract_info.outputs.version }}
        with:
          github-token: ${{ secrets.ORG_REPO_TOKEN }} # To trigger another workflow
          script: |
            await github.rest.git.createRef({
              owner: context.repo.owner,
              repo: context.repo.repo,
              ref: `refs/tags/v${process.env.VERSION}`,
              sha: context.sha
            });

      # When v0.50.0 is released, a release branch "release/v0.50" is created.
      - name: Create release branch for patch versions
        if: ${{ endsWith(steps.extract_info.outputs.version, '.0') }}
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
        env:
          RELEASE_BRANCH: ${{ steps.extract_info.outputs.release_branch }}
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }} # Should not trigger the workflow again
          script: |
            const releaseBranch = process.env.RELEASE_BRANCH;
            await github.rest.git.createRef({
              owner: context.repo.owner,
              repo: context.repo.repo,
              ref: `refs/heads/${releaseBranch}`,
              sha: context.sha
            });
      

      # Add release branch to rulesets to enable merge queue
      - name: Add release branch to rulesets
        if: ${{ endsWith(steps.extract_info.outputs.version, '.0') }}
        env:
          GITHUB_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}
          RELEASE_BRANCH: ${{ steps.extract_info.outputs.release_branch }}
        shell: bash
        run: |
          RULESET_ID=$(gh api /repos/${GITHUB_REPOSITORY}/rulesets --jq '.[] | select(.name=="release") | .id')
          gh api /repos/${GITHUB_REPOSITORY}/rulesets/$RULESET_ID | jq '{conditions}' | jq ".conditions.ref_name.include += [\"refs/heads/${RELEASE_BRANCH}\"]" | gh api --method put --input - /repos/${GITHUB_REPOSITORY}/rulesets/$RULESET_ID

      # Since skip-github-release is specified, googleapis/release-please-action doesn't delete the label from PR.
      # This label prevents the subsequent PRs from being created. Therefore, we need to delete it ourselves.
      # cf. https://github.com/googleapis/release-please?tab=readme-ov-file#release-please-bot-does-not-create-a-release-pr-why
      - name: Remove the label from PR
        if: ${{ steps.extract_info.outputs.pr_number }}
        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
        env:
          PR_NUMBER: ${{ steps.extract_info.outputs.pr_number }}
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const prNumber = parseInt(process.env.PR_NUMBER, 10);
            github.rest.issues.removeLabel({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: prNumber,
              name: 'autorelease: pending'
            });
release-pr-check .github/workflows/release-pr-check.yaml
Triggers
pull_request
Runs on
ubuntu-latest
Jobs
check-pr-author
Commands
  • if [ "$PR_AUTHOR" != "aqua-bot" ]; then echo "::error::This branch is intended for automated backporting by bot. Please refer to the documentation:" echo "::error::https://trivy.dev/docs/latest/community/maintainer/backporting/" exit 1 fi
View raw YAML
name: Backport PR Check

on:
  pull_request:
    branches:
      - 'release/v*'

jobs:
  check-pr-author:
    runs-on: ubuntu-latest
    steps:
      - name: Check PR author
        id: check_author
        env:
          PR_AUTHOR: ${{ github.event.pull_request.user.login }}
        run: |
          if [ "$PR_AUTHOR" != "aqua-bot" ]; then
            echo "::error::This branch is intended for automated backporting by bot. Please refer to the documentation:"
            echo "::error::https://trivy.dev/docs/latest/community/maintainer/backporting/"
            exit 1
          fi
reusable-release .github/workflows/reusable-release.yaml
Triggers
workflow_call
Runs on
ubuntu-latest-m
Jobs
release
Actions
sigstore/cosign-installer, docker/setup-qemu-action, docker/setup-buildx-action, docker/login-action, docker/login-action, docker/login-action, CycloneDX/gh-gomod-generate-sbom, goreleaser/goreleaser-action, docker/build-push-action, actions/attest
Commands
  • echo "${PLATFORMS}"
  • echo "$GPG_KEY" > gpg.key
  • mkdir tmp
  • rm gpg.key
View raw YAML
name: Reusable release
on:
  workflow_call:
    inputs:
      goreleaser_config:
        description: 'file path to GoReleaser config'
        required: true
        type: string
      goreleaser_options:
        description: 'GoReleaser options separated by spaces'
        default: ''
        required: false
        type: string
    secrets:
      DOCKERHUB_USER:
        required: true
      DOCKERHUB_TOKEN:
        required: true
      ECR_ACCESS_KEY_ID:
        required: true
      ECR_SECRET_ACCESS_KEY:
        required: true
      GPG_KEY:
        required: true
      ORG_REPO_TOKEN:
        required: true
      GPG_PASSPHRASE:
        required: true

env:
  GH_USER: "aqua-bot"

jobs:
  release:
    name: Release
    runs-on: ubuntu-latest-m
    env:
      DOCKER_CLI_EXPERIMENTAL: "enabled"
    permissions:
      id-token: write # For cosign
      packages: write # For GHCR
      contents: read  # Not required for public repositories, but for clarity
      attestations: write # For build provenance attestations
    steps:
      - name: Cosign install
        uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0

      - name: Set up QEMU
        uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0

      - name: Set up Docker Buildx
        id: buildx
        uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0

      - name: Show available Docker Buildx platforms
        env:
          PLATFORMS: ${{ steps.buildx.outputs.platforms }}
        run: echo "${PLATFORMS}"

      - name: Login to docker.io registry
        uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
        with:
          username: ${{ secrets.DOCKERHUB_USER }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Login to ghcr.io registry
        uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
        with:
          registry: ghcr.io
          username: ${{ env.GH_USER }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Login to ECR
        uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
        with:
          registry: public.ecr.aws
          username: ${{ secrets.ECR_ACCESS_KEY_ID }}
          password: ${{ secrets.ECR_SECRET_ACCESS_KEY }}

      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          fetch-depth: 0
          persist-credentials: false

      - name: Setup Go
        uses: ./.github/actions/setup-go

      - name: Generate SBOM
        uses: CycloneDX/gh-gomod-generate-sbom@efc74245d6802c8cefd925620515442756c70d8f # v2.0.0
        with:
          args: mod -licenses -json -output bom.json
          version: ^v1

      - name: "save gpg key"
        env:
          GPG_KEY: ${{ secrets.GPG_KEY }}
        run: |
          echo "$GPG_KEY" > gpg.key

      # Create tmp dir for GoReleaser
      - name: "create tmp dir"
        run: |
          mkdir tmp    

      - name: GoReleaser
        id: goreleaser
        uses: goreleaser/goreleaser-action@ec59f474b9834571250b370d4735c50f8e2d1e29 # v7.0.0
        with:
          version: v2.1.0
          args: release -f=${{ inputs.goreleaser_config}} ${{ inputs.goreleaser_options}}
        env:
          GITHUB_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}
          NFPM_DEFAULT_RPM_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
          GPG_FILE: "gpg.key"
          TMPDIR: "tmp"

      - name: "remove gpg key"
        run: |
          rm gpg.key

      # Push images to registries (only for canary build)
      # The custom Dockerfile.canary is necessary
      # because GoReleaser Free doesn't support pushing images with the `--snapshot` flag.
      - name: Build and push
        if: ${{ inputs.goreleaser_config == 'goreleaser-canary.yml' }}
        uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
        with:
          platforms: linux/amd64, linux/arm64
          file: ./Dockerfile.canary # path to Dockerfile
          context: .
          push: true
          tags: |
            aquasec/trivy:canary
            ghcr.io/aquasecurity/trivy:canary
            public.ecr.aws/aquasecurity/trivy:canary

      - name: Generate build provenance attestations
        if: ${{ inputs.goreleaser_config != 'goreleaser-canary.yml' }}
        uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
        with:
          subject-checksums: dist/trivy_${{ fromJSON(steps.goreleaser.outputs.metadata).version }}_checksums.txt

      # This workflow is only triggered by tag pushes (release.yaml: on.push.tags), which require
      # maintainer access. Fork PRs cannot reach this code path, so the cache cannot be poisoned
      # by external contributors. The key is scoped to github.sha, making cross-run collisions
      # impossible. Cache is written here and read only by the deploy-packages job in release.yaml.
      - name: Cache Trivy binaries
        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 # zizmor: ignore[cache-poisoning]
        with:
          path: dist/
          # use 'github.sha' to create a unique cache folder for each run.
          # use 'github.workflow' to create a unique cache folder if some runs have same commit sha.
          # e.g. build and release runs
          key: ${{ runner.os }}-bins-${{github.workflow}}-${{github.sha}}
scan security .github/workflows/scan.yaml
Triggers
schedule, workflow_dispatch
Runs on
ubuntu-latest
Jobs
build
Actions
knqyf263/trivy-issue-action
View raw YAML
name: Scan vulnerabilities
on:
  schedule:
    - cron: '0 0 * * *'
  workflow_dispatch:

jobs:
  build:
    name: Scan Go vulnerabilities
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Run Trivy vulnerability scanner and create GitHub issues
        uses: knqyf263/trivy-issue-action@4466f52d1401b66dd2a2ab9e0c40cddc021829ec # v0.0.6
        with:
          assignee: knqyf263
          severity: CRITICAL
          skip-dirs: integration,examples,pkg
          label: kind/security
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
semantic-pr .github/workflows/semantic-pr.yaml
Triggers
pull_request
Runs on
ubuntu-latest
Jobs
validate
Commands
  • set -euo pipefail # Convert env vars to regex alternatives, excluding comments and empty lines TYPES_REGEX=$(echo "$VALID_TYPES" | grep -v '^$' | paste -sd '|') SCOPES_REGEX=$(echo "$VALID_SCOPES" | grep -v '^$' | grep -v '^#' | paste -sd '|') # Basic format check (should match: type(scope): description or type: description) FORMAT_REGEX="^[a-z]+(\([a-z0-9+]+\))?!?: .+$" if ! echo "$PR_TITLE" | grep -qE "$FORMAT_REGEX"; then echo "Error: Invalid PR title format" echo "Expected format: <type>(<scope>): <description> or <type>: <description>" echo "Examples:" echo " feat(vuln): add new vulnerability detection" echo " fix: correct parsing logic" echo " docs(kubernetes): update installation guide" echo -e "\nCurrent title: $PR_TITLE" exit 1 fi # Extract type and scope for validation TYPE=$(echo "$PR_TITLE" | sed -E 's/^([a-z]+)(\([a-z0-9+]+\))?!?: .+$/\1/') SCOPE=$(echo "$PR_TITLE" | sed -E 's/^[a-z]+\(([a-z0-9+]+)\)!?: .+$/\1/; t; s/.*//') # Validate type if ! echo "$VALID_TYPES" | grep -qx "$TYPE"; then echo "Error: Invalid type '${TYPE}'" echo -e "\nValid types:" echo "$VALID_TYPES" | grep -v '^$' | sed 's/^/- /' echo -e "\nCurrent title: $PR_TITLE" exit 1 fi # Validate scope if present if [ -n "$SCOPE" ]; then if ! echo "$VALID_SCOPES" | grep -v '^#' | grep -qx "$SCOPE"; then echo "Error: Invalid scope '${SCOPE}'" echo -e "\nValid scopes:" echo "$VALID_SCOPES" | grep -v '^$' | grep -v '^#' | sed 's/^/- /' echo -e "\nCurrent title: $PR_TITLE" exit 1 fi fi echo "PR title validation passed ✅" echo "Current title: $PR_TITLE"
View raw YAML
name: "Validate PR Title"

on:
  pull_request:
    types:
      - opened
      - edited
      - synchronize

jobs:
  validate:
    name: Validate PR title
    runs-on: ubuntu-latest
    steps:
      - name: Validate PR title
        shell: bash
        env:
          PR_TITLE: ${{ github.event.pull_request.title }}
          # Valid types
          VALID_TYPES: |
            feat
            fix
            docs
            style
            refactor
            perf
            test
            build
            ci
            chore
            revert
            release
          # Valid scopes categorized by area
          VALID_SCOPES: |
            # Scanners
            vuln
            misconf
            secret
            license

            # Targets
            image
            fs
            repo
            sbom
            server
            k8s
            aws
            vm
            plugin

            # OS
            activestate
            alpine
            wolfi
            chainguard
            redhat
            alma
            rocky
            mariner
            oracle
            debian
            ubuntu
            amazon
            suse
            photon
            echo
            distroless
            windows
            minimos
            rootio
            seal

            # Languages
            ruby
            php
            python
            nodejs
            rust
            dotnet
            java
            go
            c
            c++
            elixir
            dart
            swift
            bitnami
            conda
            julia

            # Package types
            os
            lang

            # IaC
            kubernetes
            dockerfile
            terraform
            cloudformation

            # Container
            docker
            podman
            containerd
            oci

            # SBOM
            sbom
            spdx
            cyclonedx

            # Misc
            cli
            flag
            purl
            vex
            helm
            report
            db
            parser
            deps
        run: |
          set -euo pipefail

          # Convert env vars to regex alternatives, excluding comments and empty lines
          TYPES_REGEX=$(echo "$VALID_TYPES" | grep -v '^$' | paste -sd '|')
          SCOPES_REGEX=$(echo "$VALID_SCOPES" | grep -v '^$' | grep -v '^#' | paste -sd '|')

          # Basic format check (should match: type(scope): description or type: description)
          FORMAT_REGEX="^[a-z]+(\([a-z0-9+]+\))?!?: .+$"
          if ! echo "$PR_TITLE" | grep -qE "$FORMAT_REGEX"; then
            echo "Error: Invalid PR title format"
            echo "Expected format: <type>(<scope>): <description> or <type>: <description>"
            echo "Examples:"
            echo "  feat(vuln): add new vulnerability detection"
            echo "  fix: correct parsing logic"
            echo "  docs(kubernetes): update installation guide"
            echo -e "\nCurrent title: $PR_TITLE"
            exit 1
          fi

          # Extract type and scope for validation
          TYPE=$(echo "$PR_TITLE" | sed -E 's/^([a-z]+)(\([a-z0-9+]+\))?!?: .+$/\1/')
          SCOPE=$(echo "$PR_TITLE" | sed -E 's/^[a-z]+\(([a-z0-9+]+)\)!?: .+$/\1/; t; s/.*//')

          # Validate type
          if ! echo "$VALID_TYPES" | grep -qx "$TYPE"; then
            echo "Error: Invalid type '${TYPE}'"
            echo -e "\nValid types:"
            echo "$VALID_TYPES" | grep -v '^$' | sed 's/^/- /'
            echo -e "\nCurrent title: $PR_TITLE"
            exit 1
          fi

          # Validate scope if present
          if [ -n "$SCOPE" ]; then
            if ! echo "$VALID_SCOPES" | grep -v '^#' | grep -qx "$SCOPE"; then
              echo "Error: Invalid scope '${SCOPE}'"
              echo -e "\nValid scopes:"
              echo "$VALID_SCOPES" | grep -v '^$' | grep -v '^#' | sed 's/^/- /'
              echo -e "\nCurrent title: $PR_TITLE"
              exit 1
            fi
          fi

          echo "PR title validation passed ✅"
          echo "Current title: $PR_TITLE"
spdx-cron .github/workflows/spdx-cron.yaml
Triggers
schedule, workflow_dispatch
Runs on
ubuntu-24.04
Jobs
build
Actions
Skitionek/notify-microsoft-teams
Commands
  • go install tool
  • mage spdx:updateLicenseEntries if [ -n "$(git status --porcelain)" ]; then echo "Run 'mage spdx:updateLicenseEntries' and push it" echo "send_notify=true" >> $GITHUB_OUTPUT fi
View raw YAML
name: SPDX licenses cron
on:
  schedule:
    - cron: '0 0 * * 0' # every Sunday at 00:00
  workflow_dispatch:

jobs:
  build:
    name: Check if SPDX exceptions
    runs-on: ubuntu-24.04
    steps:
      - name: Check out code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Set up Go
        uses: ./.github/actions/setup-go

      - name: Install Go tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Check if SPDX license IDs and exceptions are up-to-date
        id: exceptions_check
        run: |
          mage spdx:updateLicenseEntries
          if [ -n "$(git status --porcelain)" ]; then
            echo "Run 'mage spdx:updateLicenseEntries' and push it"
            echo "send_notify=true" >> $GITHUB_OUTPUT
          fi

      - name: Microsoft Teams Notification
        uses: Skitionek/notify-microsoft-teams@b65dda7f5e6fd0960b97f923629b911890dc60b1 # main
        if: steps.exceptions_check.outputs.send_notify == 'true'
        with:
          webhook_url: ${{ secrets.TRIVY_MSTEAMS_WEBHOOK }}
          needs: ${{ toJson(needs) }}
          job: ${{ toJson(job) }}
          steps: ${{ toJson(steps) }}
stale-issues .github/workflows/stale-issues.yaml
Triggers
schedule
Runs on
ubuntu-latest
Jobs
stale
Actions
actions/stale
View raw YAML
name: "Stale PR's"
on:
  schedule:
    - cron: '0 0 * * *'
jobs:
  stale:
    timeout-minutes: 1
    runs-on: ubuntu-latest
    steps:
    - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0
      with:
        repo-token: ${{ secrets.GITHUB_TOKEN }}
        stale-pr-message: 'This PR is stale because it has been labeled with inactivity.'
        exempt-pr-labels: 'lifecycle/active'
        stale-pr-label: 'lifecycle/stale'
        days-before-stale: 60
        days-before-issue-stale: '-1'
        days-before-close: 20
        days-before-issue-close: '-1'
test matrix .github/workflows/test.yaml
Triggers
pull_request, merge_group, workflow_dispatch
Runs on
${{ matrix.operating-system }}, ubuntu-latest, ubuntu-latest, ubuntu-latest, ubuntu-latest, ubuntu-latest, ${{ matrix.operating-system }}, ubuntu-latest
Jobs
test, integration, k8s-integration, module-test, vm-test, e2e-test, build-test, zizmor
Matrix
operating-system→ macos-latest, ubuntu-latest, windows-latest
Actions
golangci/golangci-lint-action, docker/setup-docker-action, goreleaser/goreleaser-action, zizmorcore/zizmor-action
Commands
  • go mod tidy if [ -n "$(git status --porcelain)" ]; then echo "Run 'go mod tidy' and push it" exit 1 fi
  • echo "Linter failed, running 'mage lint:fix' might help to correct some errors" exit 1
  • go install tool
  • mage docs:generate if [ -n "$(git status --porcelain)" ]; then echo "Run 'mage docs:generate' and push it" exit 1 fi
  • mage test:unit
  • go install tool
  • source integration/testimages.ini IMAGE_LIST=$(skopeo list-tags docker://$TEST_IMAGES) DIGEST=$(echo "$IMAGE_LIST" | jq '.Tags += ["containerd"] | .Tags |= sort' | sha256sum | cut -d' ' -f1) echo "digest=$DIGEST" >> $GITHUB_OUTPUT
  • mage test:integration
View raw YAML
name: Test
on:
  pull_request:
      paths-ignore:
      - '**.md'
      - 'docs/**'
      - 'mkdocs.yml'
      - 'LICENSE'
      - '.release-please-manifest.json' ## don't run tests for release-please PRs
      - 'helm/trivy/Chart.yaml'
  merge_group:
  workflow_dispatch:

jobs:
  test:
    name: Test
    runs-on: ${{ matrix.operating-system }}
    strategy:
      matrix:
        operating-system: [ubuntu-latest, windows-latest, macos-latest]
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Set up Go
        uses: ./.github/actions/setup-go

      - name: go mod tidy
        run: |
          go mod tidy
          if [ -n "$(git status --porcelain)" ]; then
            echo "Run 'go mod tidy' and push it"
            exit 1
          fi
        if: matrix.operating-system == 'ubuntu-latest'

      - name: Lint
        id: lint
        uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
        with:
          version: v2.10
          args: --verbose
          skip-save-cache: true  # Restore cache from main branch but don't save new cache
        env:
          GOEXPERIMENT: jsonv2
        if: matrix.operating-system == 'ubuntu-latest'

      - name: Check if linter failed
        run: |
          echo "Linter failed, running 'mage lint:fix' might help to correct some errors"
          exit 1
        if: ${{ failure() && steps.lint.conclusion == 'failure' }}

      - name: Install tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Check if CLI references are up-to-date
        run: |
          mage docs:generate
          if [ -n "$(git status --porcelain)" ]; then
            echo "Run 'mage docs:generate' and push it"
            exit 1
          fi
        if: matrix.operating-system == 'ubuntu-latest'

      - name: Run unit tests
        run: mage test:unit

  integration:
    name: Integration Test
    runs-on: ubuntu-latest
    steps:
      - name: Check out code into the Go module directory
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      # GitHub runners were rolled back to Docker Engine v28, while tests rely on Docker Engine v29.
      # This version mismatch leads to differences in image IDs and causes integration tests to fail.
      # We explicitly install Docker Engine v29 to ensure consistent behavior.
      # Remove this temporary solution when the issue is resolved.
      # https://github.com/actions/runner-images/issues/13474
      - name: Set up Docker
        uses: docker/setup-docker-action@e43656e248c0bd0647d3f5c195d116aacf6fcaf4 # v4.7.0
        with:
          version: v29.2.1
          set-host: true

      - name: Set up Go
        uses: ./.github/actions/setup-go

      - name: Install Go tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Generate image list digest
        id: image-digest
        run: |
          source integration/testimages.ini
          IMAGE_LIST=$(skopeo list-tags docker://$TEST_IMAGES)
          DIGEST=$(echo "$IMAGE_LIST" | jq '.Tags += ["containerd"] | .Tags |= sort' | sha256sum | cut -d' ' -f1)
          echo "digest=$DIGEST" >> $GITHUB_OUTPUT

      - name: Restore test images from cache
        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
        with:
          path: integration/testdata/fixtures/images
          key: cache-test-images-${{ steps.image-digest.outputs.digest }}

      - name: Run integration tests
        run: mage test:integration

  k8s-integration:
    name: K8s Integration Test
    runs-on: ubuntu-latest
    steps:
      - name: Check out code into the Go module directory
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Set up Go
        uses: ./.github/actions/setup-go

      - name: Install Go tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Run k8s integration tests
        run: mage test:k8s

  module-test:
    name: Module Integration Test
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Set up Go
        uses: ./.github/actions/setup-go

      - name: Install tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Generate image list digest
        id: image-digest
        run: |
          source integration/testimages.ini
          IMAGE_LIST=$(skopeo list-tags docker://$TEST_IMAGES)
          DIGEST=$(echo "$IMAGE_LIST" | jq '.Tags += ["containerd"] | .Tags |= sort' | sha256sum | cut -d' ' -f1)
          echo "digest=$DIGEST" >> $GITHUB_OUTPUT

      - name: Restore test images from cache
        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
        with:
          path: integration/testdata/fixtures/images
          key: cache-test-images-${{ steps.image-digest.outputs.digest }}

      - name: Run module integration tests
        shell: bash
        run: |
          mage test:module

  vm-test:
    name: VM Integration Test
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Set up Go
        uses: ./.github/actions/setup-go

      - name: Install Go tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Generate image list digest
        id: image-digest
        run: |
          source integration/testimages.ini
          IMAGE_LIST=$(skopeo list-tags docker://$TEST_VM_IMAGES)
          DIGEST=$(echo "$IMAGE_LIST" | jq '.Tags |= sort' | sha256sum | cut -d' ' -f1)
          echo "digest=$DIGEST" >> $GITHUB_OUTPUT

      - name: Restore test VM images from cache
        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
        with:
          path: integration/testdata/fixtures/vm-images
          key: cache-test-vm-images-${{ steps.image-digest.outputs.digest }}

      - name: Run vm integration tests
        run: |
          mage test:vm

  e2e-test:
    name: E2E Test
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Set up Go
        uses: ./.github/actions/setup-go

      - name: Install Go tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Run E2E tests
        run: mage test:e2e

  build-test:
    name: Build Test
    runs-on: ${{ matrix.operating-system }}
    strategy:
      matrix:
        operating-system: [ubuntu-latest, windows-latest, macos-latest]
    env:
      DOCKER_CLI_EXPERIMENTAL: "enabled"
    steps:
    # The go-build (GOCACHE env) directory requires a large amount of free disk space.
    - name: Free up disk space
      if: matrix.operating-system == 'ubuntu-latest'
      run: |
        sudo rm -rf /usr/local/lib/android
        sudo rm -rf /usr/share/dotnet
        sudo rm -rf /opt/ghc
        sudo rm -rf /opt/hostedtoolcache/CodeQL
        sudo docker image prune --all --force
        df -h

    - name: Checkout
      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      with:
        persist-credentials: false

    - name: Set up Go
      uses: ./.github/actions/setup-go

    - name: Determine GoReleaser ID
      id: goreleaser_id
      shell: bash
      run: |
        if [ "${{ matrix.operating-system }}" == "windows-latest" ]; then
          echo "id=--id build-windows" >> $GITHUB_OUTPUT
        elif [ "${{ matrix.operating-system }}" == "macos-latest" ]; then
          echo "id=--id build-macos --id build-bsd" >> $GITHUB_OUTPUT
        else
          echo "id=--id build-linux" >> $GITHUB_OUTPUT
        fi

    - name: Run GoReleaser
      uses: goreleaser/goreleaser-action@ec59f474b9834571250b370d4735c50f8e2d1e29 # v7.0.0
      with:
        version: v2.1.0
        args: build --snapshot --clean --timeout 90m ${{ steps.goreleaser_id.outputs.id }}

  # This job intentionally runs on all PRs (not scoped to .github/ path changes)
  # to keep all checks in one place. The scan itself is scoped to .github/ via the action input.
  zizmor:
    name: Lint GitHub Actions
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2
        with:
          inputs: .github/
          advanced-security: false
test-docs .github/workflows/test-docs.yaml
Triggers
pull_request
Runs on
ubuntu-latest
Jobs
build-documents
Commands
  • python -m pip install --upgrade pip setuptools wheel pip install -r docs/build/requirements.txt
  • git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
  • mike deploy test
View raw YAML
name: Test docs
on:
  pull_request:
    paths:
      - 'docs/**'
      - 'mkdocs.yml'
jobs:
  build-documents:
    name: Documentation Test
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      with:
        fetch-depth: 0
        persist-credentials: true
    - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
      with:
        python-version: 3.x
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip setuptools wheel
        pip install -r docs/build/requirements.txt
    - name: Configure the git user
      run: |
        git config user.name "github-actions[bot]"
        git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
    - name: Deploy the dev documents
      run: mike deploy test
triage security .github/workflows/triage.yaml
Triggers
discussion, workflow_dispatch
Runs on
ubuntu-latest
Jobs
label
View raw YAML
name: Triage Discussion
on:
  discussion:
    types: [created]
  workflow_dispatch:
    inputs:
      discussion_num:
        required: true
jobs:
  label:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
      - uses: ./.github/actions/trivy-triage
        with:
          discussion_num: ${{ github.event.inputs.discussion_num }}