feat(ci): automated npm publishing via trusted publishing#228
Conversation
- iOS SDK 5.7.1 → 5.7.2 - Android SDK 5.7.1 → 5.7.3 - Update all package versions, tests, and documentation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The previous resolution `>=3.1.3` resolved to minimatch 10.x (ESM-only), which broke babel-plugin-istanbul/test-exclude in Jest coverage runs. Pin to `~3.1.3` (resolves to 3.1.5) which includes the security fix while remaining CommonJS-compatible. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add publish.yml workflow triggered on GitHub release - Publishes all 5 packages with OIDC provenance (no secrets needed) - Includes version verification against release tag - Modify ci.yml to support workflow_call for reuse from publish.yml - Fix repository.url in package.json files for npm provenance Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR introduces automated npm publishing via OIDC trusted publishing (no long-lived secrets) triggered on GitHub release creation, alongside a version bump from 5.7.1 to 5.7.2 across all five packages. The CI workflow is refactored to support Key findings:
Confidence Score: 3/5
|
| Filename | Overview |
|---|---|
| .github/workflows/publish.yml | New OIDC-based npm publish workflow triggered on GitHub release. Has two issues: publish steps are not idempotent (missing --if-not-exists), and npm@latest is unpinned. |
| .github/workflows/ci.yml | Replaced push trigger with workflow_call to allow reuse from publish.yml. As a side effect, CI no longer runs automatically on direct commits to main. |
| packages/purchasely/package.json | Version bumped to 5.7.2 and repository URL updated, but the directory field is missing from the repository object — unlike all other packages in this PR. This will break npm provenance for the main package. |
| packages/amazon/package.json | Version bumped to 5.7.2, repository field correctly converted to object with git+https URL and directory field for npm provenance. |
| packages/google/package.json | Version bumped to 5.7.2, repository URL fixed to git+https format with directory field for provenance. |
| packages/huawei/package.json | Version bumped to 5.7.2, repository field converted from bare string to correct object format with directory field. |
| packages/android-player/package.json | Version bumped to 5.7.2, repository URL fixed to git+https format with directory field for provenance. |
| package.json | minimatch resolution changed from >=3.1.3 to ~3.1.3, downgrading the resolved version from 10.2.4 to 3.1.5. Likely intentional for compatibility with tooling that uses the v3 API, but means security patches in newer minor/major versions will be missed. |
| packages/purchasely/src/index.ts | Version constant purchaselyVersion bumped from 5.7.1 to 5.7.2 in line with the package.json change. |
| packages/purchasely/react-native-purchasely.podspec | iOS Purchasely SDK dependency bumped from 5.7.1 to 5.7.2, consistent with the version bump. |
Sequence Diagram
sequenceDiagram
participant Dev as Developer
participant GH as GitHub
participant CI as ci.yml (reusable)
participant Pub as publish.yml
participant npm as npmjs.com
Dev->>GH: gh release create 5.7.2
GH->>Pub: release.published event
Pub->>CI: workflow_call (prerequisite)
CI-->>Pub: lint / test / build-android / build-ios pass
Pub->>Pub: Setup Node.js + npm (OIDC)
Pub->>Pub: yarn install + yarn all:prepare
Pub->>Pub: Verify all package.json versions == tag
Pub->>npm: npm publish --provenance (react-native-purchasely)
Pub->>npm: npm publish --provenance (@purchasely/google)
Pub->>npm: npm publish --provenance (@purchasely/amazon)
Pub->>npm: npm publish --provenance (@purchasely/huawei)
Pub->>npm: npm publish --provenance (@purchasely/android-player)
npm-->>Dev: 5 packages live on npm registry
Comments Outside Diff (2)
-
packages/purchasely/package.json, line 52-55 (link)Missing
directoryfield for npm provenanceThe
repositoryobject forreact-native-purchasely(the main package) is missing thedirectoryfield that all other packages in this PR now include. The PR description explicitly states the fix must "point to repo root withdirectoryfield", yet this package — the most important one in the monorepo — does not have it.Without
directory, npm provenance will not correctly identifypackages/purchaselyas the package subdirectory within the monorepo.Prompt To Fix With AI
This is a comment left during a code review. Path: packages/purchasely/package.json Line: 52-55 Comment: **Missing `directory` field for npm provenance** The `repository` object for `react-native-purchasely` (the main package) is missing the `directory` field that all other packages in this PR now include. The PR description explicitly states the fix must "point to repo root with `directory` field", yet this package — the most important one in the monorepo — does not have it. Without `directory`, npm provenance will not correctly identify `packages/purchasely` as the package subdirectory within the monorepo. How can I resolve this? If you propose a fix, please make it concise.
-
.github/workflows/ci.yml, line 1-9 (link)CI no longer runs on direct pushes to
mainThe
pushtrigger has been dropped entirely. CI now only runs viaworkflow_call(frompublish.yml) and on pull requests targetingmain. Any direct commit tomain— a hotfix, an automated bot commit, a dependency-update merge — will not trigger CI automatically.If the intent is to ensure CI always validates the
mainbranch state after a merge, consider re-adding thepushtrigger alongsideworkflow_call:Prompt To Fix With AI
This is a comment left during a code review. Path: .github/workflows/ci.yml Line: 1-9 Comment: **CI no longer runs on direct pushes to `main`** The `push` trigger has been dropped entirely. CI now only runs via `workflow_call` (from `publish.yml`) and on pull requests targeting `main`. Any direct commit to `main` — a hotfix, an automated bot commit, a dependency-update merge — will not trigger CI automatically. If the intent is to ensure CI always validates the `main` branch state after a merge, consider re-adding the `push` trigger alongside `workflow_call`: How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: packages/purchasely/package.json
Line: 52-55
Comment:
**Missing `directory` field for npm provenance**
The `repository` object for `react-native-purchasely` (the main package) is missing the `directory` field that all other packages in this PR now include. The PR description explicitly states the fix must "point to repo root with `directory` field", yet this package — the most important one in the monorepo — does not have it.
Without `directory`, npm provenance will not correctly identify `packages/purchasely` as the package subdirectory within the monorepo.
```suggestion
"repository": {
"type": "git",
"url": "git+https://github.com/Purchasely/Purchasely-ReactNative.git",
"directory": "packages/purchasely"
},
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: .github/workflows/publish.yml
Line: 56-74
Comment:
**Publish steps are not idempotent — workflow cannot be safely retried**
If the workflow fails mid-way (e.g., packages 1–2 publish successfully but package 3 fails due to a transient network error), re-running the workflow will immediately fail on the already-published packages because npm rejects publishing an existing version. This creates an unrecoverable partial-publish state that requires manual intervention.
Adding `--if-not-exists` makes each step idempotent: npm skips re-publishing an already-published version and exits 0, so a re-run of the workflow will safely publish only the remaining packages.
```suggestion
- name: Publish react-native-purchasely
working-directory: packages/purchasely
run: npm publish --access public --provenance --if-not-exists
- name: Publish @purchasely/react-native-purchasely-google
working-directory: packages/google
run: npm publish --access public --provenance --if-not-exists
- name: Publish @purchasely/react-native-purchasely-amazon
working-directory: packages/amazon
run: npm publish --access public --provenance --if-not-exists
- name: Publish @purchasely/react-native-purchasely-huawei
working-directory: packages/huawei
run: npm publish --access public --provenance --if-not-exists
- name: Publish @purchasely/react-native-purchasely-android-player
working-directory: packages/android-player
run: npm publish --access public --provenance --if-not-exists
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: .github/workflows/publish.yml
Line: 35-36
Comment:
**Unpinned `npm@latest` introduces non-determinism**
`npm install -g npm@latest` installs whatever the current latest npm release is at the time of each workflow run. This means:
- The published artifact may vary between runs depending on which npm version is active.
- A future npm major release could silently change publish behavior or break the workflow.
- It conflicts with the step's own comment that specifies `>= 11.5.1` — the actual installed version is never verified.
Pin to an explicit version (and update it deliberately via Dependabot or a renovate rule):
```suggestion
- name: Ensure npm >= 11.5.1 (required for trusted publishing)
run: npm install -g npm@11
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: .github/workflows/ci.yml
Line: 1-9
Comment:
**CI no longer runs on direct pushes to `main`**
The `push` trigger has been dropped entirely. CI now only runs via `workflow_call` (from `publish.yml`) and on pull requests targeting `main`. Any direct commit to `main` — a hotfix, an automated bot commit, a dependency-update merge — will not trigger CI automatically.
If the intent is to ensure CI always validates the `main` branch state after a merge, consider re-adding the `push` trigger alongside `workflow_call`:
```suggestion
on:
workflow_call:
push:
branches:
- main
pull_request:
branches:
- main
```
How can I resolve this? If you propose a fix, please make it concise.Last reviewed commit: 75114e9
| - name: Publish react-native-purchasely | ||
| working-directory: packages/purchasely | ||
| run: npm publish --access public --provenance | ||
|
|
||
| - name: Publish @purchasely/react-native-purchasely-google | ||
| working-directory: packages/google | ||
| run: npm publish --access public --provenance | ||
|
|
||
| - name: Publish @purchasely/react-native-purchasely-amazon | ||
| working-directory: packages/amazon | ||
| run: npm publish --access public --provenance | ||
|
|
||
| - name: Publish @purchasely/react-native-purchasely-huawei | ||
| working-directory: packages/huawei | ||
| run: npm publish --access public --provenance | ||
|
|
||
| - name: Publish @purchasely/react-native-purchasely-android-player | ||
| working-directory: packages/android-player | ||
| run: npm publish --access public --provenance |
There was a problem hiding this comment.
Publish steps are not idempotent — workflow cannot be safely retried
If the workflow fails mid-way (e.g., packages 1–2 publish successfully but package 3 fails due to a transient network error), re-running the workflow will immediately fail on the already-published packages because npm rejects publishing an existing version. This creates an unrecoverable partial-publish state that requires manual intervention.
Adding --if-not-exists makes each step idempotent: npm skips re-publishing an already-published version and exits 0, so a re-run of the workflow will safely publish only the remaining packages.
| - name: Publish react-native-purchasely | |
| working-directory: packages/purchasely | |
| run: npm publish --access public --provenance | |
| - name: Publish @purchasely/react-native-purchasely-google | |
| working-directory: packages/google | |
| run: npm publish --access public --provenance | |
| - name: Publish @purchasely/react-native-purchasely-amazon | |
| working-directory: packages/amazon | |
| run: npm publish --access public --provenance | |
| - name: Publish @purchasely/react-native-purchasely-huawei | |
| working-directory: packages/huawei | |
| run: npm publish --access public --provenance | |
| - name: Publish @purchasely/react-native-purchasely-android-player | |
| working-directory: packages/android-player | |
| run: npm publish --access public --provenance | |
| - name: Publish react-native-purchasely | |
| working-directory: packages/purchasely | |
| run: npm publish --access public --provenance --if-not-exists | |
| - name: Publish @purchasely/react-native-purchasely-google | |
| working-directory: packages/google | |
| run: npm publish --access public --provenance --if-not-exists | |
| - name: Publish @purchasely/react-native-purchasely-amazon | |
| working-directory: packages/amazon | |
| run: npm publish --access public --provenance --if-not-exists | |
| - name: Publish @purchasely/react-native-purchasely-huawei | |
| working-directory: packages/huawei | |
| run: npm publish --access public --provenance --if-not-exists | |
| - name: Publish @purchasely/react-native-purchasely-android-player | |
| working-directory: packages/android-player | |
| run: npm publish --access public --provenance --if-not-exists |
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/publish.yml
Line: 56-74
Comment:
**Publish steps are not idempotent — workflow cannot be safely retried**
If the workflow fails mid-way (e.g., packages 1–2 publish successfully but package 3 fails due to a transient network error), re-running the workflow will immediately fail on the already-published packages because npm rejects publishing an existing version. This creates an unrecoverable partial-publish state that requires manual intervention.
Adding `--if-not-exists` makes each step idempotent: npm skips re-publishing an already-published version and exits 0, so a re-run of the workflow will safely publish only the remaining packages.
```suggestion
- name: Publish react-native-purchasely
working-directory: packages/purchasely
run: npm publish --access public --provenance --if-not-exists
- name: Publish @purchasely/react-native-purchasely-google
working-directory: packages/google
run: npm publish --access public --provenance --if-not-exists
- name: Publish @purchasely/react-native-purchasely-amazon
working-directory: packages/amazon
run: npm publish --access public --provenance --if-not-exists
- name: Publish @purchasely/react-native-purchasely-huawei
working-directory: packages/huawei
run: npm publish --access public --provenance --if-not-exists
- name: Publish @purchasely/react-native-purchasely-android-player
working-directory: packages/android-player
run: npm publish --access public --provenance --if-not-exists
```
How can I resolve this? If you propose a fix, please make it concise.| - name: Ensure npm >= 11.5.1 (required for trusted publishing) | ||
| run: npm install -g npm@latest |
There was a problem hiding this comment.
Unpinned
npm@latest introduces non-determinism
npm install -g npm@latest installs whatever the current latest npm release is at the time of each workflow run. This means:
- The published artifact may vary between runs depending on which npm version is active.
- A future npm major release could silently change publish behavior or break the workflow.
- It conflicts with the step's own comment that specifies
>= 11.5.1— the actual installed version is never verified.
Pin to an explicit version (and update it deliberately via Dependabot or a renovate rule):
| - name: Ensure npm >= 11.5.1 (required for trusted publishing) | |
| run: npm install -g npm@latest | |
| - name: Ensure npm >= 11.5.1 (required for trusted publishing) | |
| run: npm install -g npm@11 |
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/publish.yml
Line: 35-36
Comment:
**Unpinned `npm@latest` introduces non-determinism**
`npm install -g npm@latest` installs whatever the current latest npm release is at the time of each workflow run. This means:
- The published artifact may vary between runs depending on which npm version is active.
- A future npm major release could silently change publish behavior or break the workflow.
- It conflicts with the step's own comment that specifies `>= 11.5.1` — the actual installed version is never verified.
Pin to an explicit version (and update it deliberately via Dependabot or a renovate rule):
```suggestion
- name: Ensure npm >= 11.5.1 (required for trusted publishing)
run: npm install -g npm@11
```
How can I resolve this? If you propose a fix, please make it concise.
Summary
publish.ymlworkflow triggered on GitHub release creationworkflow_callChanges
.github/workflows/publish.yml— new workflow for automated npm publish.github/workflows/ci.yml— replacepushtrigger withworkflow_callto enable reusepackages/*/package.json— fixrepository.urlfields for npm provenance (must point to repo root withdirectoryfield)npm Trusted Publisher setup required
Configure on npmjs.com for each package (Access → Trusted Publishers → GitHub Actions):
react-native-purchasely@purchasely/react-native-purchasely-google@purchasely/react-native-purchasely-amazon@purchasely/react-native-purchasely-huawei@purchasely/react-native-purchasely-android-playerSettings: repo =
Purchasely/Purchasely-ReactNative, workflow =publish.ymlRelease process
gh release create 5.7.2 --target main --title "5.7.2" --notes "..."npm view react-native-purchasely versionTest plan
🤖 Generated with Claude Code