Skip to content

Require PR approval for release tagging#6243

Merged
ajpallares merged 2 commits into
mainfrom
pallares/auto-merge-release-pr
Mar 2, 2026
Merged

Require PR approval for release tagging#6243
ajpallares merged 2 commits into
mainfrom
pallares/auto-merge-release-pr

Conversation

@ajpallares

@ajpallares ajpallares commented Feb 10, 2026

Copy link
Copy Markdown
Member

Motivation

The release workflow currently allows tagging a release branch without verifying that the PR has been reviewed and approved. This adds a safeguard to ensure the release PR is properly approved before the tag is created.

Description

Adds a validate_pr_approved step to the tag-release-branch CI job that verifies the release PR has been approved by an org member with write permissions before the git tag is created. If the PR is not approved, the job fails and the tag is not pushed.


Note

Medium Risk
Changes the release-tagging CI path to hard-fail if the approval check is missing/misconfigured, which could block release tags from being created.

Overview
Adds a new guard step to the CircleCI tag-release-branch job that runs fastlane run validate_pr_approved before tag_current_branch, ensuring the release PR is approved by an org member with write permissions prior to tagging.

Written by Cursor Bugbot for commit 120734c. This will update automatically on new commits. Configure here.

@ajpallares ajpallares requested a review from a team as a code owner February 10, 2026 16:57
@ajpallares ajpallares changed the title Require PR approval for release tagging + auto-merge release PR after… Require PR approval for release tagging + auto-merge release PR after deploy Feb 10, 2026
@claude

claude Bot commented Feb 10, 2026

Copy link
Copy Markdown

Code review

Found 2 issues that need to be addressed:


Issue 1: Missing Content-Type header in get_pr_review_decision (Critical)

Location:

request = Net::HTTP::Post.new(uri)
request["Authorization"] = "bearer #{token}"
request.body = {
query: "{ repository(owner: \"RevenueCat\", name: \"#{REPO_NAME}\") { pullRequest(number: #{pr_number}) { reviewDecision } } }"
}.to_json
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(request) }

The get_pr_review_decision function sends a POST request to the GitHub GraphQL API without setting the Content-Type: application/json header.

Ruby's Net::HTTP::Post does not automatically set Content-Type when .body is assigned directly. The GitHub GraphQL API requires this header to parse the JSON request body. Without it, the API will not process the query correctly, causing .dig("data", "repository", "pullRequest", "reviewDecision") to return nil, which falls back to "NONE". This will make the check_release_pr_approved lane always report the PR as unapproved, blocking all releases.

Other API calls in this file correctly set the Content-Type header (see

# Make request
headers = {"Circle-Token": circle_token, "Content-Type": "application/json", "Accept": "application/json"}
data = {
).

Suggested fix - Add this line after line 2377:

request["Content-Type"] = "application/json"

Issue 2: Missing Content-Type header in merge_pr

Location:

request = Net::HTTP::Put.new(uri)
request["Authorization"] = "token #{token}"
request.body = { merge_method: merge_method }.to_json
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(request) }

The merge_pr function sends a PUT request to the GitHub REST API with a JSON body but without setting Content-Type: application/json.

Without this header, the GitHub API will not parse the JSON body correctly, causing the merge_method: "squash" parameter to be ignored. The merge would either fail or default to a regular merge commit instead of the intended squash merge.

Suggested fix - Add this line after line 2394:

request["Content-Type"] = "application/json"

Both issues follow the same pattern: JSON is being sent in the request body (.to_json) but the Content-Type header is not set, which prevents the GitHub API from parsing the body correctly.

@rickvdl rickvdl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice work! I think this makes sense

Comment thread fastlane/Fastfile Outdated

@tonidero tonidero left a comment

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.

I think if we just move to use fastlane's github_action it would be simpler? Other than that, looks good to me!

Comment thread fastlane/Fastfile Outdated
Comment thread fastlane/Fastfile Outdated
Comment thread fastlane/Fastfile Outdated
Comment thread fastlane/Fastfile Outdated
Comment thread fastlane/Fastfile Outdated
Comment thread .circleci/config.yml Outdated
Comment thread .circleci/config.yml Outdated
- install-rubydocker-dependencies
- run:
name: Merge release PR
command: bundle exec fastlane merge_release_pr

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.

I wonder how this will work in case the branch is not up to date with main... It might not work correctly right? I guess it would fail in that case, and we would need human intervention, which is not too bad I guess, so let's try with this! 👍

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Comment thread .circleci/config.yml
Base automatically changed from pallares/change-ci-structure-for-PRs to main February 23, 2026 09:59
Add a `validate_pr_approved` check to `tag-release-branch` that verifies
the release PR has been approved by an org member with write permissions
before the tag is created. This prevents tagging a release before the PR
is properly reviewed.

Made-with: Cursor
@ajpallares ajpallares force-pushed the pallares/auto-merge-release-pr branch from b18e253 to 2214f5d Compare February 26, 2026 17:50
@ajpallares ajpallares changed the title Require PR approval for release tagging + auto-merge release PR after deploy Require PR approval for release tagging Feb 26, 2026
@ajpallares ajpallares requested review from a team and facumenzella February 26, 2026 17:54
@ajpallares

Copy link
Copy Markdown
Member Author

I split the automerge part of this PR into #6363, as requiring PR approval for release tagging and enabling automerge of release PRs are actually two separate things

@ajpallares ajpallares requested a review from Copilot February 26, 2026 18:14

Copilot AI left a comment

Copy link
Copy Markdown

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 adds a validation step to ensure release PRs are approved before tagging. The change prevents accidental release tags from being created without proper review.

Changes:

  • Added a PR approval validation step to the tag-release-branch CI job that runs before the git tag is created

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

@tonidero tonidero left a comment

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.

🚢

Comment thread .circleci/config.yml
command: |
echo "Verifying that the release PR has been approved by an org member with write permissions."
echo "This check prevents tagging a release before the PR is properly reviewed."
bundle exec fastlane run validate_pr_approved

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.

I'm slightly concerned that some folks might approve the hold job without approving the PR, then move to other stuff, and this will take probably a few seconds since it needs to spin the machine to trigger... But I don't have a better option. Let's go with this for now and see how people feel about it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, that's a good point. Let's see how this works. We can always undo 👍

@ajpallares ajpallares merged commit 4189d5d into main Mar 2, 2026
12 of 13 checks passed
@ajpallares ajpallares deleted the pallares/auto-merge-release-pr branch March 2, 2026 08:27
facumenzella pushed a commit that referenced this pull request Mar 5, 2026
Add a `validate_pr_approved` check to `tag-release-branch` that verifies
the release PR has been approved by an org member with write permissions
before the tag is created. This prevents tagging a release before the PR
is properly reviewed.

Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants