Skip to content

ci: create PR and automatically merge when a dependency updates#695

Merged
vladfrangu merged 8 commits intomasterfrom
ci/pr-only-when-ci-fails
Mar 13, 2026
Merged

ci: create PR and automatically merge when a dependency updates#695
vladfrangu merged 8 commits intomasterfrom
ci/pr-only-when-ci-fails

Conversation

@vladfrangu
Copy link
Member

@vladfrangu vladfrangu commented Feb 20, 2026

This change will keep opening the PR for new image versions but will automatically merge it

@vladfrangu vladfrangu requested review from B4nan and Copilot February 20, 2026 14:15
@vladfrangu vladfrangu added the adhoc Ad-hoc unplanned task added during the sprint. label Feb 20, 2026
@github-actions github-actions bot added this to the 134th sprint - Tooling team milestone Feb 20, 2026
@github-actions github-actions bot added the t-tooling Issues with this label are in the ownership of the tooling team. label Feb 20, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the template-update automation to wait for CI on the pushed update branch and, when CI succeeds, merge directly to master (falling back to opening/updating a PR only when needed).

Changes:

  • Add a “wait for CI” polling/watch step to find the lint_and_test.yaml run for the exact pushed commit.
  • Attempt an automatic merge to master on successful CI and delete the update branch afterward.
  • Add workflow-level concurrency to lint_and_test.yaml to cancel in-progress runs per ref.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
.github/workflows/update-templates.yml Adds CI wait logic, auto-merge to master on success, and PR creation/update fallback with CI status in the body.
.github/workflows/lint_and_test.yaml Adds concurrency configuration to reduce redundant overlapping CI runs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@vladfrangu vladfrangu changed the title ci: only PR on CI failure, else automatically merge ci: only PR when CI does not pass, else automatically merge Feb 20, 2026
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@B4nan
Copy link
Member

B4nan commented Feb 23, 2026

Here is what claude thinks about it:

⏺ Staff Engineer Review: PR #695

  Title: ci: only PR when CI does not pass, else automatically merge
  Author: @vladfrangu | Files changed: 2 | +109 / -24

  ---
  Summary

  The PR changes the update-templates.yml workflow so that automated template updates are merged directly to master when CI passes, falling back to creating a PR only when CI fails or the merge can't be completed. It also adds a concurrency group to
  lint_and_test.yaml. The goal is to reduce the number of PRs requiring manual intervention.

  ---
  Critical Issues

  1. Runner billing: idle wait burns Actions minutes

  gh run watch keeps the update-templates runner alive and billable while the entire lint_and_test.yaml pipeline (Python linting, type checking, Node tests, Python tests, LLM AI tests, Docker builds) completes. That could be 15-30+ minutes of an idle
  runner per template update. Since these are triggered by repository_dispatch (potentially multiple base images in quick succession), this could add up materially.

  Recommendation: Consider restructuring this as a two-workflow approach: the update workflow pushes the branch and exits, then a separate workflow (triggered by the CI completion via workflow_run) handles the merge-or-PR decision. This eliminates idle
  billing entirely.

  2. Merging untested code when master advances

  The CI runs against the branch HEAD. The merge via repos/$REPO/merges API creates a new merge commit that is never tested. If master has advanced since the branch was created (e.g., another template update just merged), the resulting merge commit
  contains untested combinations. For template archive updates this risk is low, but it's an architectural smell.

  Recommendation: At minimum, add a fast-forward check before merging (verify the branch is based on current master HEAD). Alternatively, use gh pr merge with auto-merge + required checks, which is the GitHub-native solution for exactly this problem.

  3. || true on gh run watch swallows real failures (line ~135 in diff)

  gh run watch "$RUN_ID" --exit-status || true

  If gh run watch fails due to a network/auth error (not a CI failure), the subsequent gh run view may also fail or return null. The conclusion propagates as empty, which then falls through to the PR creation step where CI_RUN_ID is set, so the status
  message says "CI failed" — which is misleading.

  Recommendation: Capture the exit code and distinguish between "CI failed" and "watch itself errored":

  set +e
  gh run watch "$RUN_ID" --exit-status
  WATCH_EXIT=$?
  set -e

  if [ $WATCH_EXIT -ne 0 ]; then
    CONCLUSION=$(gh run view "$RUN_ID" --json conclusion --jq '.conclusion' 2>/dev/null || echo "unknown")
  else
    CONCLUSION="success"
  fi

  ---
  Medium Issues

  4. Concurrency group will cancel scheduled runs vs push runs

  In lint_and_test.yaml:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

  Scheduled (cron) runs use the default branch ref (refs/heads/master). A push to master during a nightly run (or vice versa) will cancel the in-progress one. Since the nightly run is a full regression check, having it cancelled by a template update push
  is undesirable.

  Fix: Include the event name:
  group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}

  5. Merge creates a merge commit — is that intentional?

  The repos/$REPO/merges API always creates a merge commit. Looking at the git history, some automated commits are direct pushes (like chore: Update template archives [skip ci]). Is a merge commit the desired merge strategy here, or should this be a
  fast-forward / squash? Since the branch is reset to origin/master + one commit, a fast-forward would be cleaner if the branch hasn't diverged.

  6. Missing [skip ci] on the merge commit

  Recent automated commits use [skip ci] (f50448d, 6caa24a, 7f232b9). The merge commit message (chore: Update templates for base image: ...) will trigger another full CI run on master immediately after one just passed on the branch. This doubles CI cost
  for every successful auto-merge.

  ---
  Minor Issues

  7. Force push still runs when there's no commit (line 90-91 of current file)

  The existing git push --force is outside the if block, so it runs even when there are no changes. The new flow handles this correctly via if: steps.commit-and-push.outputs.committed == 'true', but the unnecessary force push remains. Low priority but
  worth cleaning up.

  8. PR body CI status messaging is imprecise

  The success branch says:
  "CI passed, but the automatic merge into master did not complete"

  But this step also runs when wait-for-ci timed out or returned an unknown conclusion (since merged would not be 'true'). The logic should distinguish between "CI passed + merge failed" vs "CI never completed + no merge attempted."

  ---
  What's Good

  - The core idea is sound — auto-merging passing template updates reduces toil
  - The fallback to PR creation when things go wrong is a good safety net
  - CI status in the PR body gives reviewers immediate context
  - Concurrency on lint_and_test.yaml is a welcome addition (with the fix above)

  ---
  Suggested Architecture (if scope allows)

  The cleanest solution would be:

  1. update-templates.yml — pushes the branch, exits immediately
  2. lint_and_test.yaml — runs CI as-is (already triggered by push)
  3. New auto-merge-templates.yml — triggered by workflow_run on lint_and_test.yaml completion for ci/* branches, handles merge-or-PR logic

  This eliminates idle billing, avoids the gh run watch fragility, and separates concerns cleanly. It's more files but less complexity in each.

The critical issues don't feel that critical to me, but sharing it anyway, the suggested architecture might be an interesting bit.

@vladfrangu
Copy link
Member Author

I need to also apply the Copilot reviews, but I do love how AI wrote this and AI is roasting it back 😄

@vladfrangu
Copy link
Member Author

I do like the idea of PRs with auto-merge tho, might to that route

@B4nan
Copy link
Member

B4nan commented Mar 4, 2026

Where are we with this one?

@danpoletaev danpoletaev force-pushed the ci/pr-only-when-ci-fails branch from 6f8cdb0 to b7e7650 Compare March 6, 2026 21:52
@B4nan B4nan force-pushed the ci/pr-only-when-ci-fails branch from b7e7650 to 6f8cdb0 Compare March 6, 2026 22:49
@vladfrangu vladfrangu changed the title ci: only PR when CI does not pass, else automatically merge ci: create PR and automatically merge when a dependency updates Mar 13, 2026
@vladfrangu vladfrangu requested a review from Copilot March 13, 2026 10:37
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
vladfrangu and others added 2 commits March 13, 2026 12:56
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@vladfrangu
Copy link
Member Author

vladfrangu commented Mar 13, 2026

Woo, it works!

@vladfrangu vladfrangu merged commit 771b694 into master Mar 13, 2026
36 checks passed
@vladfrangu vladfrangu deleted the ci/pr-only-when-ci-fails branch March 13, 2026 11:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

adhoc Ad-hoc unplanned task added during the sprint. t-tooling Issues with this label are in the ownership of the tooling team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants