-
Notifications
You must be signed in to change notification settings - Fork 0
chore: add Dependabot security-only update config #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ee86714
c304a56
763a4a8
14f99d3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| version: 2 | ||
| updates: | ||
| - package-ecosystem: "cargo" | ||
| directory: "/" | ||
| schedule: | ||
| interval: "weekly" | ||
| open-pull-requests-limit: 0 | ||
| labels: | ||
| - "security" | ||
| - "dependencies" | ||
|
|
||
| - package-ecosystem: "github-actions" | ||
| directory: "/" | ||
| schedule: | ||
| interval: "weekly" | ||
| open-pull-requests-limit: 10 | ||
| labels: | ||
| - "security" | ||
| - "dependencies" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| # Dependabot auto-merge workflow | ||
| # | ||
| # Requires repository secrets: | ||
| # APP_ID — GitHub App ID with contents:write and pull-requests:write | ||
| # APP_PRIVATE_KEY — GitHub App private key | ||
| # | ||
| # Auto-approves and enables auto-merge for Dependabot PRs that are: | ||
| # - GitHub Actions updates (patch or minor version bumps) | ||
| # - Security updates for any ecosystem (patch or minor) | ||
| # - Indirect (transitive) dependency updates | ||
| # Major version updates are always left for human review. | ||
| # Uses --auto so the merge waits for all required CI checks to pass. | ||
| # | ||
| # Safety model: application ecosystems use open-pull-requests-limit: 0 in | ||
| # dependabot.yml, so the only app-ecosystem PRs Dependabot can create are | ||
| # security updates. This workflow adds defense-in-depth by also checking | ||
| # the package ecosystem. | ||
| name: Dependabot auto-merge | ||
|
|
||
| on: | ||
| pull_request_target: | ||
| branches: | ||
| - main | ||
|
|
||
| permissions: {} | ||
|
|
||
| jobs: | ||
| dependabot: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| pull-requests: read | ||
| if: github.event.pull_request.user.login == 'dependabot[bot]' | ||
| steps: | ||
| - name: Dependabot metadata | ||
| id: metadata | ||
| uses: dependabot/fetch-metadata@ffa630c65fa7e0ecfa0625b5ceda64399aea1b36 # v2 | ||
| with: | ||
| github-token: "${{ secrets.GITHUB_TOKEN }}" | ||
|
|
||
| - name: Determine if auto-merge eligible | ||
| id: eligible | ||
| run: | | ||
| UPDATE_TYPE="${{ steps.metadata.outputs.update-type }}" | ||
| DEP_TYPE="${{ steps.metadata.outputs.dependency-type }}" | ||
| ECOSYSTEM="${{ steps.metadata.outputs.package-ecosystem }}" | ||
|
|
||
| # Must be patch, minor, or indirect | ||
| if [[ "$UPDATE_TYPE" != "version-update:semver-patch" && \ | ||
| "$UPDATE_TYPE" != "version-update:semver-minor" && \ | ||
| "$DEP_TYPE" != "indirect" ]]; then | ||
| echo "eligible=false" >> "$GITHUB_OUTPUT" | ||
| echo "Skipping: major update requires human review" | ||
don-petry marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| exit 0 | ||
| fi | ||
|
|
||
| # GitHub Actions version updates are always eligible | ||
| # App ecosystem PRs can only exist as security updates (limit: 0) | ||
| echo "eligible=true" >> "$GITHUB_OUTPUT" | ||
| echo "Auto-merge eligible: ecosystem=$ECOSYSTEM update=$UPDATE_TYPE" | ||
|
|
||
| - name: Generate app token | ||
| if: steps.eligible.outputs.eligible == 'true' | ||
| id: app-token | ||
| uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3 | ||
| with: | ||
| app-id: ${{ secrets.APP_ID }} | ||
| private-key: ${{ secrets.APP_PRIVATE_KEY }} | ||
|
|
||
| - name: Approve and enable auto-merge | ||
| if: steps.eligible.outputs.eligible == 'true' | ||
| run: | | ||
| gh pr review --approve "$PR_URL" | ||
| gh pr merge --auto --squash "$PR_URL" | ||
| env: | ||
| PR_URL: ${{ github.event.pull_request.html_url }} | ||
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,217 @@ | ||
| # Dependency vulnerability audit | ||
| # | ||
| # Auto-detects ecosystems present in the repository and runs the appropriate | ||
| # audit tool. Fails the build if any dependency has a known security advisory. | ||
don-petry marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| # | ||
| # Add "dependency-audit" as a required status check in branch protection. | ||
don-petry marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| # | ||
| # Pinned tool versions (update deliberately): | ||
| # govulncheck v1.1.4 | cargo-audit 0.22.1 | pip-audit 2.9.0 | ||
| name: Dependency audit | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: [main] | ||
| push: | ||
| branches: [main] | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| detect: | ||
|
Comment on lines
+19
to
+22
|
||
| name: Detect ecosystems | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| npm: ${{ steps.check.outputs.npm }} | ||
| pnpm: ${{ steps.check.outputs.pnpm }} | ||
| gomod: ${{ steps.check.outputs.gomod }} | ||
| cargo: ${{ steps.check.outputs.cargo }} | ||
| pip: ${{ steps.check.outputs.pip }} | ||
| steps: | ||
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 | ||
|
|
||
| - name: Detect package ecosystems | ||
| id: check | ||
| run: | | ||
| # npm — look for package-lock.json anywhere (excluding node_modules) | ||
| if find . -name 'package-lock.json' -not -path '*/node_modules/*' | grep -q .; then | ||
| echo "npm=true" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "npm=false" >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| # pnpm — look for pnpm-lock.yaml anywhere | ||
| if find . -name 'pnpm-lock.yaml' -not -path '*/node_modules/*' | grep -q .; then | ||
| echo "pnpm=true" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "pnpm=false" >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| # Go modules — detect via go.mod (not go.sum, which may not exist) | ||
| if find . -name 'go.mod' -not -path '*/vendor/*' | grep -q .; then | ||
|
Comment on lines
+41
to
+52
|
||
| echo "gomod=true" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "gomod=false" >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| # Cargo — detect via Cargo.toml anywhere (lockfile may not exist for libraries) | ||
| if find . -name 'Cargo.toml' -not -path '*/target/*' | grep -q .; then | ||
| echo "cargo=true" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "cargo=false" >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| # Python — detect pyproject.toml or requirements.txt anywhere | ||
| if find . -name 'pyproject.toml' -not -path '*/.venv/*' -not -path '*/venv/*' | grep -q . || \ | ||
| find . -name 'requirements.txt' -not -path '*/.venv/*' -not -path '*/venv/*' | grep -q .; then | ||
| echo "pip=true" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "pip=false" >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| audit-npm: | ||
| name: npm audit | ||
| needs: detect | ||
| if: needs.detect.outputs.npm == 'true' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 | ||
|
|
||
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | ||
| with: | ||
| node-version: "lts/*" | ||
|
|
||
| - name: Audit npm dependencies | ||
| run: | | ||
| # Audit each package-lock.json found in the repo | ||
| status=0 | ||
| while IFS= read -r dir; do | ||
| echo "::group::npm audit $dir" | ||
| if ! (cd "$dir" && npm audit --audit-level=low); then | ||
| status=1 | ||
| fi | ||
| echo "::endgroup::" | ||
| done < <(find . -name 'package-lock.json' -not -path '*/node_modules/*' -exec dirname {} \;) | ||
| exit $status | ||
|
|
||
| audit-pnpm: | ||
| name: pnpm audit | ||
| needs: detect | ||
| if: needs.detect.outputs.pnpm == 'true' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 | ||
|
|
||
| - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4 | ||
|
|
||
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | ||
| with: | ||
| node-version: "lts/*" | ||
| cache: "pnpm" | ||
|
|
||
| - name: Audit pnpm dependencies | ||
| run: | | ||
| # Audit each pnpm-lock.yaml found in the repo | ||
| status=0 | ||
| while IFS= read -r dir; do | ||
| echo "::group::pnpm audit $dir" | ||
| if ! (cd "$dir" && pnpm audit --audit-level low); then | ||
| status=1 | ||
| fi | ||
| echo "::endgroup::" | ||
| done < <(find . -name 'pnpm-lock.yaml' -not -path '*/node_modules/*' -exec dirname {} \;) | ||
| exit $status | ||
|
|
||
| audit-go: | ||
| name: govulncheck | ||
| needs: detect | ||
| if: needs.detect.outputs.gomod == 'true' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 | ||
|
|
||
| - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5 | ||
| with: | ||
| go-version: "stable" | ||
|
|
||
| - name: Install govulncheck | ||
| run: go install golang.org/x/vuln/cmd/govulncheck@v1.1.4 | ||
|
|
||
| - name: Audit Go dependencies | ||
| run: | | ||
| status=0 | ||
| while IFS= read -r dir; do | ||
| echo "::group::govulncheck $dir" | ||
| if ! (cd "$dir" && govulncheck ./...); then | ||
|
Comment on lines
+142
to
+146
|
||
| status=1 | ||
| fi | ||
|
Comment on lines
+144
to
+148
|
||
| echo "::endgroup::" | ||
| done < <(find . -name 'go.mod' -not -path '*/vendor/*' -exec dirname {} \;) | ||
| exit $status | ||
|
|
||
| audit-cargo: | ||
| name: cargo audit | ||
| needs: detect | ||
| if: needs.detect.outputs.cargo == 'true' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 | ||
|
|
||
| - uses: dtolnay/rust-toolchain@stable | ||
|
|
||
| - name: Install cargo-audit | ||
| run: cargo install cargo-audit@0.22.1 --locked | ||
|
|
||
| - name: Audit Cargo dependencies | ||
| run: | | ||
| # cargo audit operates on Cargo.lock at workspace root | ||
| # For workspaces, a single audit at root covers all crates | ||
| status=0 | ||
| while IFS= read -r dir; do | ||
| echo "::group::cargo audit $dir" | ||
| if ! (cd "$dir" && cargo generate-lockfile 2>/dev/null; cargo audit); then | ||
| status=1 | ||
| fi | ||
| echo "::endgroup::" | ||
| done < <(find . -name 'Cargo.toml' -not -path '*/target/*' -exec dirname {} \; | sort -u) | ||
| exit $status | ||
|
|
||
| audit-pip: | ||
| name: pip-audit | ||
| needs: detect | ||
| if: needs.detect.outputs.pip == 'true' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 | ||
|
|
||
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | ||
| with: | ||
| python-version: "3.x" | ||
|
|
||
| - name: Install pip-audit | ||
| run: pip install pip-audit==2.9.0 | ||
|
|
||
| - name: Audit Python dependencies | ||
| run: | | ||
| status=0 | ||
| # Audit each Python project found in the repo | ||
| while IFS= read -r dir; do | ||
| echo "::group::pip-audit $dir" | ||
| if [ -f "$dir/pyproject.toml" ]; then | ||
| if ! pip-audit "$dir"; then | ||
| status=1 | ||
| fi | ||
| elif [ -f "$dir/requirements.txt" ]; then | ||
| if ! pip-audit -r "$dir/requirements.txt"; then | ||
| status=1 | ||
| fi | ||
| fi | ||
| echo "::endgroup::" | ||
| done < <( | ||
| { | ||
| find . -name 'pyproject.toml' -not -path '*/.venv/*' -not -path '*/venv/*' -exec dirname {} \; | ||
| find . -name 'requirements.txt' -not -path '*/.venv/*' -not -path '*/venv/*' -exec dirname {} \; | ||
| } | sort -u | ||
| ) | ||
| exit $status | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR description says Cargo updates should be security-only (open-pull-requests-limit 0), but this entry is configured to allow up to 10 version-update PRs. If the intent is security-only for Cargo, set open-pull-requests-limit to 0 so Dependabot doesn’t open routine version bump PRs.