Skip to content

Conversation

@james-toussaint
Copy link
Collaborator

Releases upgradeable package with actionable workflow.

PR Checklist

  • Tests
  • Tested on a release-v5.5 patched branch in a forked repo:
image image image
  • Documentation

@changeset-bot
Copy link

changeset-bot bot commented Oct 23, 2025

⚠️ No Changeset found

Latest commit: 9581bae

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@james-toussaint james-toussaint marked this pull request as ready for review October 23, 2025 11:15
@james-toussaint james-toussaint requested a review from a team as a code owner October 23, 2025 11:15
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 23, 2025

Walkthrough

Introduces a new GitHub Actions workflow that automates the release process for upgradeable OpenZeppelin contracts. The workflow triggers manually via workflow_dispatch, validates that the upgradeable commit references the correct vanilla commit, reads the version from package.json, determines appropriate npm and git tags based on semantic versioning, publishes the package to npm with the correct tag, and creates a GitHub Release with accompanying release notes. The workflow includes environment variable configuration and security measures for token handling.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "Add workflow to release upgradeable package" directly and clearly summarizes the main change introduced in the changeset. The raw summary confirms that the PR introduces a new GitHub Actions workflow named "Release Upgradeable" that automates releasing an upgradeable OpenZeppelin contract package. The title is concise, specific, and avoids unnecessary noise or vague language. It effectively communicates the primary change from a developer's perspective.
Description Check ✅ Passed The pull request description "Releases upgradeable package with actionable workflow" is clearly related to the changeset. While brief, it conveys meaningful information about the purpose of the workflow being added—enabling automated releases of the upgradeable package. The description is further supported by the PR checklist, which includes evidence of testing, screenshots demonstrating successful Git releases and NPM releases. The description does not contain completely non-descriptive terms like "misc updates" or "stuff," and it meaningfully relates to the actual workflow implementation described in the raw summary.
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

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: 1

♻️ Duplicate comments (3)
.github/workflows/release-upgradeable.yml (3)

12-12: Update UPGRADEABLE_REPO to production repository before merging.

Line 12 explicitly points to a test fork (james-toussaint/openzeppelin-contracts-upgradeable) with a TODO comment. This must be updated to the canonical OpenZeppelin repository.

Apply this diff:

-      UPGRADEABLE_REPO: james-toussaint/openzeppelin-contracts-upgradeable # TODO: Update repo before merging
+      UPGRADEABLE_REPO: OpenZeppelin/openzeppelin-contracts-upgradeable

This aligns with the past review suggestion.


70-70: Fix release notes tag reference—dependency on test-only block.

Line 70 uses ${OLD_GIT_TAG} to fetch release notes from the vanilla repo. However, OLD_GIT_TAG is only defined within the test block at line 47. When the test block is removed (per the previous comment), this variable will be undefined, and the release creation will fail.

Replace OLD_GIT_TAG with GIT_TAG (after the test block is removed):

-            --notes="$(gh release view ${OLD_GIT_TAG} --repo="${VANILLA_REPO}" --json body -q .body)" `#TODO: Update tag before merging` \
+            --notes="$(gh release view ${GIT_TAG} --repo="${VANILLA_REPO}" --json body -q .body)" \

This aligns with the past review suggestion and resolves the SC2034 warning about OLD_GIT_TAG being unused.


45-51: Remove test/development block before merging.

Lines 45–51 contain temporary modifications for testing (timestamped versions, custom package scope, modified package.json) and are explicitly marked TODO: Remove block before merging. This code must not ship to production.

Remove this entire block:

-          ### [START BLOCK] TODO: Remove block before merging
-          TIMESTAMPED_VERSION="${VERSION}-$(date +%s)"
-          OLD_GIT_TAG="${GIT_TAG}"
-          GIT_TAG="${GIT_TAG}-$(date +%s)" # incremental git tag for testing
-          sed -i'' -e 's/openzeppelin\/contracts-upgradeable/james-toussaint\/contracts-upgradeable/g' contracts/package.json # custom scope for testing
-          sed -i'' -e "s/${VERSION}/${TIMESTAMPED_VERSION}/g" contracts/package.json && head contracts/package.json # incremental npm package version for testing
-          ### [END BLOCK]

This removal will cascade to fixing line 70 (see next comment).

🧹 Nitpick comments (1)
.github/workflows/release-upgradeable.yml (1)

52-62: Address shellcheck quoting warnings.

Static analysis flags several SC2086 warnings (double quote to prevent globbing and word splitting) at lines 52–62. While these are typically informational, adding quotes around variable expansions improves robustness:

Apply quotes for consistency and safety:

-          npm ci
-          bash scripts/git-user-config.sh
-          git tag -m {,}${GIT_TAG}
-          CI=true git push origin tag ${GIT_TAG}
+          npm ci
+          bash scripts/git-user-config.sh
+          git tag -m {,}"${GIT_TAG}"
+          CI=true git push origin tag "${GIT_TAG}"

Also add quotes around the cd command context:

-          cd contracts
+          cd "contracts"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1cf1377 and 8b5132b.

📒 Files selected for processing (1)
  • .github/workflows/release-upgradeable.yml (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: lint workflows
.github/workflows/release-upgradeable.yml

[error] 20-20: shellcheck reported issue in this script: SC2086:info:1:56: Double quote to prevent globbing and word splitting [shellcheck]

🪛 GitHub Check: lint
.github/workflows/release-upgradeable.yml

[failure] 66-66:
shellcheck reported issue in this script: SC2086:info:5:3: Double quote to prevent globbing and word splitting


[failure] 66-66:
shellcheck reported issue in this script: SC2086:info:4:30: Double quote to prevent globbing and word splitting


[failure] 30-30:
shellcheck reported issue in this script: SC2086:info:30:30: Double quote to prevent globbing and word splitting


[failure] 30-30:
shellcheck reported issue in this script: SC2086:info:25:29: Double quote to prevent globbing and word splitting


[failure] 30-30:
shellcheck reported issue in this script: SC2086:info:24:15: Double quote to prevent globbing and word splitting


[failure] 30-30:
shellcheck reported issue in this script: SC2034:warning:17:1: OLD_GIT_TAG appears unused. Verify use (or export if used externally)


[failure] 30-30:
shellcheck reported issue in this script: SC2086:info:14:78: Double quote to prevent globbing and word splitting


[failure] 30-30:
shellcheck reported issue in this script: SC2091:warning:1:6: Remove surrounding $() to avoid executing output (or use eval if intentional)


[failure] 20-20:
shellcheck reported issue in this script: SC2086:info:1:56: Double quote to prevent globbing and word splitting

🔇 Additional comments (1)
.github/workflows/release-upgradeable.yml (1)

63-71: Confirm environment and token handling post-fixes.

The GitHub release step uses GH_TOKEN_UPGRADEABLE for authentication. Once the test block and tag references are corrected, verify that the token and repository context are correctly scoped.

After applying the above fixes, validate:

  1. The workflow runs end-to-end without errors
  2. GIT_TAG is correctly resolved in the release creation step
  3. Release notes are fetched from the vanilla repo using the correct tag

This will confirm no side effects from the test-block removal.

Copy link
Member

@ernestognw ernestognw left a comment

Choose a reason for hiding this comment

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

Looks in the right direction, but in my opinion it'll be better if we split the job into more structured steps and keeping the scripts outside of this workflow declaration.

Comment on lines 62 to 63
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
Copy link
Member

Choose a reason for hiding this comment

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

We wouldn't need the NPM_TOKEN if we're using trusted publishers. See #6009

I just added the trusted publisher for the upgradeable package:
Captura de pantalla 2025-10-29 a la(s) 4 02 37 p m

Suggested change
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Also, I think this would fail because the NPM_TOKEN is only available in the npm environment

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

NPM_TOKEN has been removed.

Right now package.json url repository needs to be updated from upgradeable to vanilla to comply with provenance:

Comment on lines 67 to 72
run: |
gh release create "${GIT_TAG}" \
--repo="${UPGRADEABLE_REPO}" \
--title="${GIT_TAG}" \
--notes="$(gh release view "${OLD_GIT_TAG}" --repo="${VANILLA_REPO}" --json body -q .body)" `# TODO: Update tag before merging` \
"${ADDITIONAL_OPTION_IF_PRERELEASE}"
Copy link
Member

Choose a reason for hiding this comment

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

We need to document that the release will not include a customized readme and that we should copy paste the one from vanilla. Ideally, it would copy it directly from vanilla but that's too overkill imo

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Content is copied from vanilla release, see --notes.

Comment on lines 35 to 44
VERSION="$(jq -r .version package.json)"
GIT_TAG="v${VERSION}"
NPM_TAG="tmp"
ADDITIONAL_OPTION_IF_PRERELEASE="--prerelease"
if [[ "${GIT_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
NPM_TAG="dev"
ADDITIONAL_OPTION_IF_PRERELEASE=""
elif [[ "${GIT_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc.[0-9]+$ ]]; then
NPM_TAG="next"
fi
Copy link
Member

Choose a reason for hiding this comment

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

In the vanilla release cycle workflow we pack first and then we publish. This allows to gather environmental values as output from the job (see the pack script). I would suggest doing the same here so that we can isolate the npm publish command and also run an integrity check

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Steps have been scoped, lmk.

Copy link
Collaborator

@Amxx Amxx left a comment

Choose a reason for hiding this comment

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

I would have expected this to be integrated into the release-cycle workflow. Something like a publish-upgradeable that is triggered by needs.state.outputs.publish == 'true'

Any reason to prefer a manual dispatch ?

Copy link
Member

@ernestognw ernestognw left a comment

Choose a reason for hiding this comment

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

Almost there

VANILLA_REPO: OpenZeppelin/openzeppelin-contracts
UPGRADEABLE_REPO: james-toussaint/openzeppelin-contracts-upgradeable # TODO: Update repo before merging
steps:
- run: echo "UPGRADEABLE_DIR=${GITHUB_WORKSPACE}/upgradeable" >> "$GITHUB_ENV"
Copy link
Member

Choose a reason for hiding this comment

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

I would pass upgradeable as a workflow input (or anothe env variable along with VANILLA_REPO and UPGRADEABLE_REPO). Essentially:

on:
  workflow_dispatch:
    inputs:
          upgradeable-path:
            description: 'The path where the upgradeable repository will be cloned under $GITHUB_WORKSPACE'
            required: true
            type: string
            default: 'upgradeable'

So that here we can do:

Suggested change
- run: echo "UPGRADEABLE_DIR=${GITHUB_WORKSPACE}/upgradeable" >> "$GITHUB_ENV"
- run: echo "UPGRADEABLE_DIR=${GITHUB_WORKSPACE}/${{ github.event.inputs.upgradeable-path }}" >> "$GITHUB_ENV"

And:

- uses: actions/checkout@v5
        with:
          repository: ${{ env.UPGRADEABLE_REPO }}
          submodules: true
          token: ${{ secrets.GH_TOKEN_UPGRADEABLE }}
          ref: ${{ github.ref }}
          path: ${{ github.event.inputs.upgradeable-path }}

This way we keep the value consistent across where it's used

Copy link
Member

Choose a reason for hiding this comment

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

Actually, on a second thought I think the path should be provided for the vanilla repository instead, this way we can echo "commit=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" && cd "${UPGRADEABLE_DIR}", then just continue normally.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants