Skip to content

DUPLO-42440: Upgrade remaining actions to Node24#112

Open
amaechiabuah wants to merge 7 commits intomainfrom
feature/node24-upgrade
Open

DUPLO-42440: Upgrade remaining actions to Node24#112
amaechiabuah wants to merge 7 commits intomainfrom
feature/node24-upgrade

Conversation

@amaechiabuah
Copy link
Copy Markdown

Summary

Eliminates all remaining Node20 deprecation warnings from this repo's actions by upgrading or replacing the 4 remaining Node20-only dependencies.

Ticket: DUPLO-42440

Approach (per reference commit guidance):

  • Upgraded azure/CLI@v2@v3v3 release only changes the Node runtime to 24
  • Replaced octokit/request-action@v2.x with inline gh api — v3 also removed support for route parameter inputs (owner, username), making a simple version bump insufficient
  • Replaced tspascoal/get-user-teams-membership@v3 with inline gh api — no Node24 version available
  • Replaced softprops/action-gh-release@v2 with inline gh release create — no Node24 version available
  • Synced stale v2 references in deprecated setup/action.yml

Note: duplocloud/version-bump@main still uses Node20 (separate repo, out of scope).

Test plan

  • Triggered GHA Experiments workflow on this branch with test jobs exercising the rules action and release script
  • All jobs passed — run #24091720795
  • Zero Node20 deprecation warnings in test run
  • Rules action correctly returns role=unknown (graceful 403 handling), isTeamMember=false, and displays output
  • Release script creates release, captures URL output, and cleans up
  • Post-merge: run Publish Version and verify softprops warning is gone (only version-bump warning should remain)

- azure/CLI@v2 → @V3 (node24)
- octokit/request-action@v2.x → @V3 (node24)
- tspascoal/get-user-teams-membership@v3 → inline gh api
- softprops/action-gh-release@v2 → inline gh release create
- Sync setup/action.yml stale v2 references
- Add temporary test workflows for verification
@qodo-code-review
Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Upgrade remaining GitHub Actions to Node24 runtime

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Replace deprecated Node20 actions with Node24 compatible alternatives
• Replace softprops/action-gh-release@v2 with inline gh release create command
• Replace octokit/request-action@v2.x with inline gh api calls
• Replace tspascoal/get-user-teams-membership@v3 with inline gh api implementation
• Upgrade azure/CLI@v2 to @v3 and sync stale v2 references in setup action
Diagram
flowchart LR
  A["Deprecated Node20 Actions"] -->|Replace| B["Inline gh CLI Commands"]
  A -->|Upgrade| C["Node24 Compatible Versions"]
  B --> D["rules/action.yml"]
  B --> E["publish.yml"]
  C --> F["action.yml & setup/action.yml"]
  D --> G["Eliminates Node20 Warnings"]
  E --> G
  F --> G
Loading

Grey Divider

File Changes

1. rules/action.yml ✨ Enhancement +24/-12

Replace deprecated actions with inline gh api calls

• Replace octokit/request-action@v2.x with inline gh api for org membership check
• Replace tspascoal/get-user-teams-membership@v3 with inline gh api loop for team membership
 validation
• Simplify output parsing by using --jq flag instead of fromJson() conversion
• Add error handling for 403 responses with graceful fallback to role=unknown

rules/action.yml


2. .github/workflows/publish.yml ✨ Enhancement +11/-10

Replace softprops action with inline gh release

• Replace softprops/action-gh-release@v2 action with inline gh release create command
• Use GH_TOKEN environment variable instead of action input parameter
• Create release body file from environment variables before calling gh release create
• Capture release URL output from gh release create command

.github/workflows/publish.yml


3. action.yml ✨ Enhancement +1/-1

Upgrade azure CLI action to v3

• Upgrade azure/CLI@v2 to @v3 for Node24 runtime support

action.yml


View more (2)
4. setup/action.yml ✨ Enhancement +4/-4

Upgrade multiple actions to Node24 versions

• Upgrade azure/login@v2 to @v3 for Node24 support
• Upgrade azure/CLI@v2 to @v3 for Node24 support
• Upgrade google-github-actions/auth@v2 to @v3 for Node24 support
• Upgrade google-github-actions/setup-gcloud@v2 to @v3 for Node24 support

setup/action.yml


5. README.md 📝 Documentation +1/-1

Update documentation for azure CLI version

• Update azure/CLI dependency reference from @v2 to @v3

README.md


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review Bot commented Apr 7, 2026

Code Review by Qodo

🐞 Bugs (1)   📘 Rule violations (0)   📎 Requirement gaps (0)
🐞\ ⛨ Security (1)

Grey Divider


Action required

1. Wrong input name used 🐞
Description
rules/action.yml references inputs.environment, but the action defines only
current_environment; this makes GHA_ENV empty and the later protection condition compare an
empty value against protected_environment, preventing the intended block from triggering.
Code

rules/action.yml[55]

    ISMEMBER: ${{ steps.actorTeams.outputs.isTeamMember }}
Evidence
The composite action declares current_environment and protected_environment inputs, but never
declares an environment input. Despite that, it reads inputs.environment for display and also
uses it in the enforcement if: condition, so the guard cannot work as intended when
inputs.environment resolves to empty.

rules/action.yml[4-16]
rules/action.yml[49-56]
rules/action.yml[67-72]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`rules/action.yml` references `inputs.environment`, but the composite action input is named `current_environment`. This causes environment display to be blank and can cause the protection gate to fail to execute.
### Issue Context
The action defines `current_environment` and `protected_environment` inputs, and later uses `inputs.environment` in both display and the enforcement `if:` expression.
### Fix Focus Areas
- rules/action.yml[4-16]
- rules/action.yml[49-56]
- rules/action.yml[67-72]
### Suggested change
- Replace `inputs.environment` with `inputs.current_environment` wherever referenced.
- If external callers already pass `environment`, consider adding an additional optional input named `environment` as a backward-compatible alias and use `inputs.environment || inputs.current_environment` in expressions.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Undeclared gh CLI dependency🐞
Description
The rules composite action now executes gh api but does not perform a preflight check or provide
a clear error message if gh is missing, which will hard-fail on runners without GitHub CLI
installed (common on self-hosted).
Code

rules/action.yml[R26-27]

+      ROLE=$(gh api "/orgs/${{ github.repository_owner }}/memberships/${{ github.event.sender.login }}" --jq '.role' 2>/dev/null) || ROLE="unknown"
+      echo "role=$ROLE" >> $GITHUB_OUTPUT
Evidence
The updated steps directly invoke the gh executable (gh api ...) and there is no preceding
installation or existence check in the action, so execution depends on runner image contents.

rules/action.yml[20-47]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`rules/action.yml` shells out to `gh api` without ensuring `gh` exists. On runners without GitHub CLI installed, the action fails with `gh: command not found`.
### Issue Context
This composite action is intended to be reusable; relying on runner preinstalls is fragile, especially for self-hosted runners.
### Fix Focus Areas
- rules/action.yml[20-47]
### Suggested change
- Add a short preflight check step before the first `gh` usage:
- `command -v gh >/dev/null 2>&1 || { echo 'GitHub CLI (gh) is required' >&2; exit 1; }`
- Optionally document this requirement in the repo README (or the action’s README if present).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment thread rules/action.yml
GH_ROLE: ${{ steps.get_user_groups.outputs.role }}
GH_TEAMS: ${{ steps.actorTeams.outputs.teams }}
GHA_ENV: ${{ inputs.environment }}
ISMEMBER: ${{ steps.actorTeams.outputs.isTeamMember }}
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.

Action required

1. Wrong input name used 🐞 Bug ⛨ Security

rules/action.yml references inputs.environment, but the action defines only
current_environment; this makes GHA_ENV empty and the later protection condition compare an
empty value against protected_environment, preventing the intended block from triggering.
Agent Prompt
### Issue description
`rules/action.yml` references `inputs.environment`, but the composite action input is named `current_environment`. This causes environment display to be blank and can cause the protection gate to fail to execute.

### Issue Context
The action defines `current_environment` and `protected_environment` inputs, and later uses `inputs.environment` in both display and the enforcement `if:` expression.

### Fix Focus Areas
- rules/action.yml[4-16]
- rules/action.yml[49-56]
- rules/action.yml[67-72]

### Suggested change
- Replace `inputs.environment` with `inputs.current_environment` wherever referenced.
- If external callers already pass `environment`, consider adding an additional optional input named `environment` as a backward-compatible alias and use `inputs.environment || inputs.current_environment` in expressions.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread .github/workflows/publish.yml Outdated
[![Publish](${{ github.server_url }}/${{ github.repository }}/actions/workflows/publish.yml/badge.svg)](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) ${{ steps.registry.outputs.badge }}

${{ steps.bump.outputs.release-notes }}
env:
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.

This is the one I had the most conversation with @kferrone about. Maybe we need to create a fork of this package as a one-off to minimize any risk of regression.

- softprops/action-gh-release@v2 → @V3 (Node24, released Apr 14)
- octokit/request-action@v2.x → @v3.0.0 (Node24, params in route string)
- Add test jobs to GHA Experiments for verification
@qodo-code-review
Copy link
Copy Markdown
Contributor

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: Test Rules Action (Node24)

Failed stage: Run rules action [❌]

Failed test name: ""

Failure summary:

  • The action failed because the step octokit/request-action@v3.0.0 attempted to call the GitHub REST
    API endpoint GET /orgs/duplocloud/memberships/amaechiabuah and received an HTTP 403 with Resource
    not accessible by integration.
  • This indicates the workflow’s token/integration (the provided GITHUB_TOKEN) does not have sufficient
    permissions to read organization membership (or the workflow is running in a context where org-level
    data is blocked, e.g., from a fork/limited token).
  • After the 403, the workflow’s action.yml template evaluation failed at ./rules/action.yml (Line: 51,
    Col: 16) with Error reading JToken..., likely because it tried to parse/use the API response as JSON
    but the response body was empty or not the expected JSON due to the authorization failure.
Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

131:  current_environment: dev
132:  protected_environment: prod
133:  team: engineering
134:  github-token: ***
135:  ##[endgroup]
136:  ##[group]Run octokit/request-action@v3.0.0
137:  with:
138:  route: GET /orgs/duplocloud/memberships/amaechiabuah
139:  mediaType: {}
140:  env:
141:  GITHUB_TOKEN: ***
142:  ##[endgroup]
143:  GET /orgs/duplocloud/memberships/amaechiabuah
144:  > mediaType: [object Object]
145:  < 403 148ms
146:  ##[error]Resource not accessible by integration - https://docs.github.com/rest/orgs/members#get-organization-membership-for-a-user
147:  ##[error]The template is not valid. /home/runner/work/actions/actions/./rules/action.yml (Line: 51, Col: 16): Error reading JToken from JsonReader. Path '', line 0, position 0.
148:  Post job cleanup.

@amaechiabuah amaechiabuah requested a review from duplodavid April 16, 2026 15:58
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