Skip to content

Conversation

@transphorm
Copy link
Member

@transphorm transphorm commented Oct 10, 2025

Summary by CodeRabbit

  • Chores
    • Enforces main branch protection: only PRs from staging are allowed.
    • Mobile deploy workflow: prevents duplicate version-bump PRs by checking for existing PRs, uses timestamped branch names to avoid collisions, and outputs the existing PR URL when skipping creation.
    • Release calendar workflow: creates PRs directly from staging to main, removes separate release branch logic, simplifies PR existence checks, and updates scheduling, prompts, and PR body notes to reflect the streamlined flow.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 10, 2025

Walkthrough

Renames a branch gate workflow to enforce staging→main PRs, updates mobile deployment workflow to use timestamped branch names and an existing-PR check, and reworks the release calendar to create PRs directly from staging to main instead of using dedicated release branches.

Changes

Cohort / File(s) Summary
Main branch gate update
.github/workflows/block-non-dev-to-main.yml
Renames workflow and changes condition to block non-staging PRs to main; failure message updated; exit behavior unchanged.
Mobile deploy PR flow
.github/workflows/mobile-deploy.yml
Branch names now include a millisecond timestamp; replaces branch-existence check with an open-PR existence check via gh pr list; if found, outputs PR URL and exits; otherwise proceeds with commit/push and PR creation.
Release calendar staging→main
.github/workflows/release-calendar.yml
Removes release-branch creation; now opens PRs directly from staging to main; updates scheduling, checks for existing PRs with head=staging, and revises PR body/message text accordingly.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Developer
  participant GH as GitHub PR Check
  Dev->>GH: Open PR to main
  GH->>GH: Check head_ref == "staging"
  alt head_ref != "staging"
    GH-->>Dev: Fail check (blocked)
  else head_ref == "staging"
    GH-->>Dev: Pass check
  end
Loading
sequenceDiagram
  autonumber
  participant WF as mobile-deploy.yml
  participant GH as GitHub API (gh)
  participant Repo as Git
  WF->>WF: Compute VERSION, TIMESTAMP
  WF->>Repo: Create branch ci/bump-mobile-version-${VERSION}-${TIMESTAMP}
  WF->>GH: gh pr list --search "is:open ... ${VERSION}"
  alt Existing PR found
    GH-->>WF: Return PR URL
    WF-->>WF: Output URL and exit
  else No PR found
    WF->>Repo: Commit version bump and push
    WF->>GH: gh pr create (staging target)
    GH-->>WF: PR URL
  end
Loading
sequenceDiagram
  autonumber
  participant Scheduler as Release Calendar
  participant GH as GitHub API (gh)
  Scheduler->>GH: Check for open PR head=staging base=main
  alt PR exists
    GH-->>Scheduler: PR URL (no action)
  else No PR
    Scheduler->>GH: Create PR from staging to main
    GH-->>Scheduler: PR URL
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

codex

Suggested reviewers

  • remicolin

Poem

Branches drift to main’s bright shore,
Staging sails, release no more.
Timestamps tick, collisions flee,
Bots check doors with quiet decree.
PRs align, the calendar sings—
Ship it clean on automated wings. 🚀

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “allow staging pull requests into main” succinctly captures the primary purpose of the changeset, which is to permit PRs from the staging branch to main; it is clear, focused, and directly related to the core modification without extraneous wording.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch justin/allow-staging-prs-to-main

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/mobile-deploy.yml (1)

969-974: Use our composite cache action instead of actions/cache.

Per the workflow guidelines, we should rely on the shared composite actions under .github/actions for dependency caching. Please replace this direct actions/cache@v4 usage with the appropriate in-repo composite (or add one for the NDK cache if it doesn’t exist yet) so we stay within policy.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 36310d0 and 5420fc2.

📒 Files selected for processing (3)
  • .github/workflows/block-non-dev-to-main.yml (2 hunks)
  • .github/workflows/mobile-deploy.yml (1 hunks)
  • .github/workflows/release-calendar.yml (4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
.github/workflows/**/*.{yml,yaml}

📄 CodeRabbit inference engine (AGENTS.md)

.github/workflows/**/*.{yml,yaml}: In GitHub workflows, use the shared composite actions in .github/actions for dependency caching instead of calling actions/cache directly
Use the cache-yarn composite action for Yarn dependency caching in workflows
Use the cache-bundler composite action for Ruby gems caching in workflows
Use the cache-gradle composite action for Gradle caching in workflows
Use the cache-pods composite action for CocoaPods caching in workflows

Files:

  • .github/workflows/mobile-deploy.yml
  • .github/workflows/block-non-dev-to-main.yml
  • .github/workflows/release-calendar.yml
🪛 actionlint (1.7.7)
.github/workflows/block-non-dev-to-main.yml

12-12: "github.head_ref" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions for more details

(expression)

Comment on lines +11 to 15
- name: Block PRs not from staging
run: |
if [[ "${{ github.head_ref }}" != "dev" ]]; then
echo "You can only merge from dev to main."
if [[ "${{ github.head_ref }}" != "staging" ]]; then
echo "You can only merge from staging to main."
exit 1
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Harden the head ref check to avoid command injection.

Interpolating ${{ github.head_ref }} directly inside the shell script leaves the step vulnerable to command injection if the branch name is crafted maliciously (see GitHub’s security guidance). Please pass the value through env: and reference the environment variable inside the script instead.

Apply this diff:

     steps:
-      - name: Block PRs not from staging
-        run: |
-          if [[ "${{ github.head_ref }}" != "staging" ]]; then
+      - name: Block PRs not from staging
+        env:
+          PR_HEAD_REF: ${{ github.head_ref }}
+        run: |
+          if [[ "${PR_HEAD_REF}" != "staging" ]]; then
             echo "You can only merge from staging to main."
             exit 1
           fi
🧰 Tools
🪛 actionlint (1.7.7)

12-12: "github.head_ref" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions for more details

(expression)

🤖 Prompt for AI Agents
.github/workflows/block-non-dev-to-main.yml lines 11-15: the workflow
interpolates ${{ github.head_ref }} directly into the shell which can allow
command injection; change the step to pass github.head_ref via env (e.g., env:
HEAD_REF: ${{ github.head_ref }}) and inside the run script reference the safe
environment variable with proper quoting and a plain string comparison (e.g., if
[[ "$HEAD_REF" != "staging" ]]; then ... exit 1; fi) to avoid executing any
injected content.

Comment on lines +1332 to 1338
EXISTING_PR=$(gh pr list --base "${TARGET_BRANCH}" --state open --json number,title,headRefName --jq ".[] | select(.title | contains(\"${VERSION}\")) | .number" | head -1)
if [ -n "$EXISTING_PR" ]; then
echo "⚠️ PR #${EXISTING_PR} already exists for version ${VERSION}"
echo "ℹ️ Skipping PR creation to avoid duplicates"
echo "ℹ️ Existing PR: https://github.com/${{ github.repository }}/pull/${EXISTING_PR}"
exit 0
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Tighten the duplicate PR detection to avoid false skips.

Filtering on title | contains("${VERSION}") will skip creating the version bump PR whenever any other open PR to ${TARGET_BRANCH} mentions the same version in its title (e.g., a manually curated release doc), which blocks the automation. Please key off the head branch name pattern instead so we only skip genuine duplicates.

Apply this diff:

-          EXISTING_PR=$(gh pr list --base "${TARGET_BRANCH}" --state open --json number,title,headRefName --jq ".[] | select(.title | contains(\"${VERSION}\")) | .number" | head -1)
+          EXISTING_PR=$(gh pr list --base "${TARGET_BRANCH}" --state open --json number,headRefName --jq ".[] | select(.headRefName | startswith(\"ci/bump-mobile-version-${VERSION}\")) | .number" | head -1)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
EXISTING_PR=$(gh pr list --base "${TARGET_BRANCH}" --state open --json number,title,headRefName --jq ".[] | select(.title | contains(\"${VERSION}\")) | .number" | head -1)
if [ -n "$EXISTING_PR" ]; then
echo "⚠️ PR #${EXISTING_PR} already exists for version ${VERSION}"
echo "ℹ️ Skipping PR creation to avoid duplicates"
echo "ℹ️ Existing PR: https://github.com/${{ github.repository }}/pull/${EXISTING_PR}"
exit 0
EXISTING_PR=$(gh pr list --base "${TARGET_BRANCH}" --state open --json number,headRefName --jq ".[] | select(.headRefName | startswith(\"ci/bump-mobile-version-${VERSION}\")) | .number" | head -1)
if [ -n "$EXISTING_PR" ]; then
echo "⚠️ PR #${EXISTING_PR} already exists for version ${VERSION}"
echo "ℹ️ Skipping PR creation to avoid duplicates"
echo "ℹ️ Existing PR: https://github.com/${{ github.repository }}/pull/${EXISTING_PR}"
exit 0
🤖 Prompt for AI Agents
In .github/workflows/mobile-deploy.yml around lines 1332-1338, the script
currently detects existing PRs by checking if the PR title contains the VERSION
which leads to false positives; update the gh pr list jq filter to inspect
headRefName instead (e.g., select(.headRefName | contains("${VERSION}")) or
match a specific branch-name pattern your workflow uses) so the check only skips
when an open PR was created from a branch that actually corresponds to this
version; replace the title-based select with a headRefName-based select and keep
the rest of the logic (echo and exit) unchanged.

@transphorm transphorm merged commit 14efa1d into staging Oct 10, 2025
13 checks passed
@transphorm transphorm deleted the justin/allow-staging-prs-to-main branch October 10, 2025 21:33
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.

2 participants