Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/self-dependabot-auto-merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Self Dependabot Auto-Merge

# Pins the released tag, not a local path, so unreleased changes never merge here.

# Fleet callers pin hand-moved tags, so a merge here reaches no other repo.

on: # zizmor: ignore[dangerous-triggers] required to run from base branch; no PR code executed here
pull_request_target:
types: [opened, synchronize, reopened]

permissions:
contents: write
pull-requests: write

jobs:
dependabot-auto-merge:
uses: smartwatermelon/github-workflows/.github/workflows/dependabot-auto-merge.yml@dependabot-auto-merge-v2
with:
trusted_namespaces: 'smartwatermelon'
42 changes: 22 additions & 20 deletions .github/workflows/self-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,26 @@ jobs:
fetch-depth: 1
persist-credentials: false

- name: Fail if dependabot-auto-merge.yml uses actions/checkout
- name: Fail if a pull_request_target workflow uses actions/checkout
run: |
file=".github/workflows/dependabot-auto-merge.yml"
if [ ! -f "$file" ]; then
echo "::notice::${file} not found — nothing to check."
exit 0
fi
# Strip comment lines first — the header comment in this file
# legitimately names `actions/checkout` while explaining why it
# must never be added, which a bare substring grep would flag
# against itself. Match the real usage form (a `uses:` step),
# not just the string appearing anywhere in the file.
if grep -v '^\s*#' "$file" | grep -qE 'uses:\s*actions/checkout'; then
echo "::error::${file} must NEVER use actions/checkout."
echo "::error::This workflow uses pull_request_target with no-checkout as its"
echo "::error::core safety property. Adding actions/checkout would expose"
echo "::error::base-branch secrets to externally-authored PR content. See the"
echo "::error::header comment in ${file} and issue #64."
exit 1
fi
echo "No actions/checkout found in ${file} — guardrail passed."
# The reusable workflow and this repo's own caller of it both
# run on pull_request_target.
for file in .github/workflows/dependabot-auto-merge.yml \
.github/workflows/self-dependabot-auto-merge.yml; do
if [ ! -f "$file" ]; then
echo "::notice::${file} not found — nothing to check."
continue
fi
# Skip comments: the header names actions/checkout on purpose.

# Match only a real `uses:` step.
if grep -v '^\s*#' "$file" | grep -qE 'uses:\s*actions/checkout'; then
echo "::error::${file} must NEVER use actions/checkout."
echo "::error::This workflow uses pull_request_target with no-checkout as its"
echo "::error::core safety property. Adding actions/checkout would expose"
echo "::error::base-branch secrets to externally-authored PR content. See the"
echo "::error::header comment in dependabot-auto-merge.yml and issue #64."
exit 1
fi
echo "No actions/checkout found in ${file} — guardrail passed."
done
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,15 @@ executes PR code: the only actions are API calls (`dependabot/fetch-metadata`,
to this file.** The guardrail below enforces this (closes #64):

- `self-review.yml`'s `guard-no-checkout` job greps this repo's own
copy of `dependabot-auto-merge.yml` and fails the PR if
copy of `dependabot-auto-merge.yml`, and its caller
`self-dependabot-auto-merge.yml`, and fails the PR if
`actions/checkout` appears.

This repo auto-merges its own Dependabot PRs through
`self-dependabot-auto-merge.yml`. It pins `@dependabot-auto-merge-v2`
rather than a local path, so an unreleased change to the reusable
workflow never decides merges here.

### Versioning

Tagged with a prefixed namespace — `dependabot-auto-merge-v1`,
Expand Down
Loading