Skip to content
Merged
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
43 changes: 43 additions & 0 deletions .github/workflows/backport.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Backport fixes to stable branch

on:
push:
branches:
- master
- main
issue_comment:
types: [created]

concurrency:
group: backport-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
Comment on lines +11 to +13
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Concurrency key doesn't distinguish between comment-triggered runs for different PRs.

issue_comment events run in the context of the default branch, meaning github.ref always resolves to e.g. refs/heads/master regardless of which PR received the comment. With the current key, all comment-triggered backport runs — even those for completely unrelated PRs — share a single concurrency slot and queue behind one another. Additionally, a push event and a comment event on master would also collide into the same group.

Include the PR number (for comment events) or github.sha (for push events) to produce distinct concurrency groups per operation:

♻️ Suggested fix
 concurrency:
-  group: backport-${{ github.workflow }}-${{ github.ref }}
+  group: >-
+    backport-${{ github.workflow }}-
+    ${{ github.event_name == 'issue_comment'
+        && github.event.issue.number
+        || github.sha }}
   cancel-in-progress: false
📝 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
concurrency:
group: backport-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
concurrency:
group: >-
backport-${{ github.workflow }}-
${{ github.event_name == 'issue_comment'
&& github.event.issue.number
|| github.sha }}
cancel-in-progress: false
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/backport.yml around lines 11 - 13, The concurrency group
is too coarse and causes unrelated comment-triggered backport runs to collide;
update the concurrency.group value (the existing "group: backport-${{
github.workflow }}-${{ github.ref }}" entry) to include the PR identifier for
comment events or the commit sha for push events by using a GitHub Actions
expression that selects github.event.issue.number (or
github.event.pull_request.number) when github.event_name == 'issue_comment' and
falls back to github.sha for other events so each comment-run for a specific PR
gets a distinct concurrency key.


permissions:
contents: write
pull-requests: write

jobs:
backport-on-push:
if: github.event_name == 'push'
uses: openwisp/openwisp-utils/.github/workflows/reusable-backport.yml@master
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

head -40 .github/workflows/backport.yml | cat -n

Repository: openwisp/django-loci

Length of output: 1510


Pin the reusable workflow to a commit SHA instead of @master.

Pinning an action to a full-length commit SHA is the only way to use an action as an immutable release. Using @master means any future change (or compromise) to openwisp/openwisp-utils is immediately picked up by this workflow, which runs with contents: write + pull-requests: write permissions and access to OPENWISP_BOT_PRIVATE_KEY. Pin actions to a full-length commit SHA-1 hash instead of branch references to prevent code changes by a malicious actor.

This applies to both line 22 (backport-on-push job) and line 37 (backport-on-comment job).

Example fix
-    uses: openwisp/openwisp-utils/.github/workflows/reusable-backport.yml@master
+    uses: openwisp/openwisp-utils/.github/workflows/reusable-backport.yml@<FULL_COMMIT_SHA>

Consider adding Dependabot configuration for github-actions to keep the pinned SHA up-to-date automatically.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/backport.yml at line 22, Pin the referenced reusable
workflow to an immutable commit SHA: replace the branch reference in the "uses:
openwisp/openwisp-utils/.github/workflows/reusable-backport.yml@master" lines
(used by jobs backport-on-push and backport-on-comment) with the full-length
commit SHA of the intended revision; update both occurrences and optionally add
Dependabot config for github-actions to keep the SHA current.

with:
commit_sha: ${{ github.sha }}
secrets:
app_id: ${{ secrets.OPENWISP_BOT_APP_ID }}
private_key: ${{ secrets.OPENWISP_BOT_PRIVATE_KEY }}

backport-on-comment:
if: >
github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
github.event.issue.pull_request.merged_at != null &&
github.event.issue.state == 'closed' &&
Comment on lines +33 to +34
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

state == 'closed' is redundant given merged_at != null.

A merged PR (merged_at != null) is always in the closed state, so line 34 provides no additional filtering. It can be removed without changing behavior.

♻️ Suggested cleanup
       github.event.issue.pull_request &&
       github.event.issue.pull_request.merged_at != null &&
-      github.event.issue.state == 'closed' &&
       contains(fromJSON('["MEMBER", "OWNER"]'), github.event.comment.author_association) &&
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/backport.yml around lines 33 - 34, Remove the redundant
`github.event.issue.state == 'closed'` condition from the workflow `if`
expression and rely solely on `github.event.issue.pull_request.merged_at !=
null`; update the `if` clause so it no longer includes
`github.event.issue.state` (keep the `github.event.issue.pull_request.merged_at
!= null` check intact) to simplify the logic in the backport workflow.

contains(fromJSON('["MEMBER", "OWNER"]'), github.event.comment.author_association) &&
startsWith(github.event.comment.body, '/backport')
uses: openwisp/openwisp-utils/.github/workflows/reusable-backport.yml@master
with:
pr_number: ${{ github.event.issue.number }}
comment_body: ${{ github.event.comment.body }}
secrets:
app_id: ${{ secrets.OPENWISP_BOT_APP_ID }}
private_key: ${{ secrets.OPENWISP_BOT_PRIVATE_KEY }}
Loading