Skip to content

fix(ci): drop brittle PAT-based dependabot automerge#901

Open
TimeToBuildBob wants to merge 2 commits into
ActivityWatch:masterfrom
TimeToBuildBob:bob/fix-dependabot-automerge
Open

fix(ci): drop brittle PAT-based dependabot automerge#901
TimeToBuildBob wants to merge 2 commits into
ActivityWatch:masterfrom
TimeToBuildBob:bob/fix-dependabot-automerge

Conversation

@TimeToBuildBob

Copy link
Copy Markdown
Contributor

Summary

Replace the PAT-dependent Dependabot auto-merge action with a direct actions/github-script merge step that runs in the trusted workflow_run context.

Why

The current workflow is failing on master with Bad credentials inside ridedott/merge-me-action, even though the repo already carries the previous PAT workaround. Using the built-in repository token here avoids the brittle external secret path entirely.

Verification

  • YAML reviewed locally
  • git diff --check
  • GitHub Actions on this PR will validate the workflow end to end

@greptile-apps

greptile-apps Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR drops the broken PAT-based ridedott/merge-me-action in favor of a small inline actions/github-script step that runs in the trusted workflow_run context and uses the built-in GITHUB_TOKEN to merge Dependabot PRs.

  • The three job-level guards (conclusion == 'success', event == 'pull_request', github.actor == 'dependabot[bot]') correctly gate execution to successful Dependabot CI runs only.
  • The merge call includes sha: context.payload.workflow_run.head_sha, which causes GitHub to return HTTP 409 if the branch has advanced since CI passed, preventing an unvalidated commit from being auto-merged.
  • The action is pinned to the mutable @v9 tag rather than a full commit SHA; pinning to a SHA is the recommended practice for any step that holds write permissions on the repository.

Confidence Score: 5/5

Safe to merge — the change removes a broken external dependency and the replacement logic is correctly guarded at every relevant checkpoint.

The inline script faithfully replicates all the safety properties the old action was supposed to provide: it only runs when the upstream Build workflow succeeds on a Dependabot pull_request event, re-fetches the PR to confirm it is still open and non-draft before merging, and passes the validated head SHA to the merge API so GitHub rejects the call if the branch has moved. No logic gaps were found that could cause an unintended merge or data loss.

No files require special attention beyond the mutable action tag noted in the inline comment.

Important Files Changed

Filename Overview
.github/workflows/dependabot-automerge.yml Replaces the failing PAT-dependent ridedott/merge-me-action with an inline actions/github-script step in the trusted workflow_run context; guards are correct (conclusion, event, actor, state, draft), and the sha TOCTOU guard is included in the merge call.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant DB as Dependabot
    participant GH as GitHub
    participant Build as Build Workflow
    participant AM as Auto-merge Workflow
    participant API as GitHub REST API

    DB->>GH: Open / update PR
    GH->>Build: Trigger pull_request event
    Build-->>GH: Workflow run completes (success/failure)
    GH->>AM: workflow_run event fired
    AM->>AM: "Check conclusion == success &&\nevent == pull_request &&\nactor == dependabot[bot]"
    AM->>API: pulls.get(pr.number)
    API-->>AM: PR details (state, draft)
    AM->>AM: "Guard: open & non-draft"
    AM->>API: "pulls.merge(pull_number, squash, sha = workflow_run.head_sha)"
    API-->>AM: 200 OK (merged) or 409 Conflict (branch moved since CI ran)
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant DB as Dependabot
    participant GH as GitHub
    participant Build as Build Workflow
    participant AM as Auto-merge Workflow
    participant API as GitHub REST API

    DB->>GH: Open / update PR
    GH->>Build: Trigger pull_request event
    Build-->>GH: Workflow run completes (success/failure)
    GH->>AM: workflow_run event fired
    AM->>AM: "Check conclusion == success &&\nevent == pull_request &&\nactor == dependabot[bot]"
    AM->>API: pulls.get(pr.number)
    API-->>AM: PR details (state, draft)
    AM->>AM: "Guard: open & non-draft"
    AM->>API: "pulls.merge(pull_number, squash, sha = workflow_run.head_sha)"
    API-->>AM: 200 OK (merged) or 409 Conflict (branch moved since CI ran)
Loading

Reviews (4): Last reviewed commit: "fix(ci): pin merge sha to prevent TOCTOU..." | Re-trigger Greptile

Comment on lines +53 to +58
await github.rest.pulls.merge({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pull.number,
merge_method: "squash",
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Missing head-SHA pin in merge call

The pulls.merge() call omits the optional sha parameter, creating a TOCTOU window: if Dependabot pushes a new version bump between when the Build workflow succeeds and when this auto-merge job runs, pull.head.sha will differ from context.payload.workflow_run.head_sha (the commit CI actually validated). GitHub will then merge the newer, unvalidated commit instead of failing. Adding sha: context.payload.workflow_run.head_sha will cause the API to return HTTP 409 Conflict when the branch has moved on since the validated build, preserving the "only merge what passed CI" guarantee.

Suggested change
await github.rest.pulls.merge({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pull.number,
merge_method: "squash",
});
await github.rest.pulls.merge({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pull.number,
merge_method: "squash",
sha: context.payload.workflow_run.head_sha,
});

@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 38.42%. Comparing base (9e466c5) to head (e609238).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #901   +/-   ##
=======================================
  Coverage   38.42%   38.42%           
=======================================
  Files          42       42           
  Lines        2225     2225           
  Branches      441      441           
=======================================
  Hits          855      855           
- Misses       1292     1349   +57     
+ Partials       78       21   -57     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

Applied the sha pin as suggested by Greptile — pulls.merge() now passes sha: context.payload.workflow_run.head_sha, so a Dependabot push between CI success and the merge step will cause a 409 conflict instead of silently merging an unvalidated commit.

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

1 similar comment
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

CI-green, mergeable, and Greptile-reviewed — waiting only on a maintainer click.

@ErikBjare Bob has pull-only access on this repo, so it can't self-merge — this is ready whenever you have a moment. (Posting this to surface the ready-to-merge backlog and stop the monitoring loop from re-flagging it every cycle.)

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

CI is green (all checks passing). Ready to merge when you get a chance.

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

Weekly stale-PR review (2026-07-17): revalidated the current head against current master. The PR remains mergeable/CLEAN and all checks pass. Leaving it open because the PAT-free Dependabot automerge fix remains valid and still needs maintainer review.

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant