Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
92 changes: 92 additions & 0 deletions .github/workflows/prepare-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Prepare Release

on:
workflow_dispatch:
inputs:
version:
description: 'Version number (e.g., 3.6.0)'
required: true
type: string
ticket:
description: 'Jira ticket number (e.g., 1234 for SDK-1234)'
required: true
type: string

permissions:
contents: write
pull-requests: write

jobs:
prepare-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
Comment thread
jferrao-itrbl marked this conversation as resolved.
Outdated

- name: Validate version format
run: |
if ! [[ "${{ github.event.inputs.version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then
echo "::error::Invalid version format. Use semantic versioning (e.g., 3.6.0 or 3.6.0-beta1)"
exit 1
fi

- uses: actions/setup-node@v4
with:
node-version: '22'

- name: Update Changelog
id: update_changelog
run: |
version="${{ github.event.inputs.version }}"
changelog_file="CHANGELOG.md"

# RN has no [Unreleased] section -- insert a new ## version header at the top
temp_file=$(mktemp)
{
echo "## $version"
echo ""
cat "$changelog_file"
} > "$temp_file"
mv "$temp_file" "$changelog_file"

- name: Bump package.json version
run: npm --no-git-tag-version --allow-same-version version "${{ github.event.inputs.version }}"

- name: Regenerate build info
run: node scripts/autoCreatePackageInfo.js

- name: Create Pull Request
uses: peter-evans/create-pull-request@4e1beaa7521e8b457b572c090b25bd3db56bf1c5 # v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
title: "SDK-${{ github.event.inputs.ticket }}: Prepare for Release ${{ github.event.inputs.version }}"
body: |
# Prepare for Release ${{ github.event.inputs.version }}

## SDK Release Checklist
- [ ] CHANGELOG.md updated with release notes under the new version header
- [ ] Version bumped in package.json
- [ ] src/itblBuildInfo.ts regenerated
- [ ] README.md reviewed (if needed)
- [ ] All tests passing
- [ ] Documentation updated (if needed)
branch: "release/SDK-${{ github.event.inputs.ticket }}-${{ github.event.inputs.version }}"
commit-message: "[SDK-${{ github.event.inputs.ticket }}]: Prepare for release ${{ github.event.inputs.version }}"
labels: release
delete-branch: true
Comment on lines +68 to +86

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

vs .github/workflows/validate-release.yml ~L34–37: Generated release PRs cannot pass existing release validation

What the code does: Prepare applies labels: release and opens a PR whose body is only the checklist. validate-release.yml runs on that label and fails unless the body contains github.com/Iterable/iterable-docs/pull/<n>.

What the spec says: “Opens a release PR with a checklist.” Project rule: release-labeled PRs must include a docs PR link (validate-release.yml; PR template “Docs PR if applicable”).

Why it conflicts: The two-step flow’s first PR is red on an existing check as soon as it is opened. The checklist says “Documentation updated (if needed)” but the validator always requires a docs URL. [caused by change]

Suggested action: The author should make the generated PR satisfy (or explicitly skip, if that is the new policy) Validate Release PR, typically a docs-PR input or a body slot the validator already accepts, before this lands.


- name: Create Draft GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
version="${{ github.event.inputs.version }}"

if gh release view "$version" &>/dev/null; then
echo "Draft release $version already exists, skipping."
else
gh release create "$version" \
--draft \
--title "$version" \
--notes "See CHANGELOG.md for release notes."
fi
74 changes: 74 additions & 0 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Publish Release

on:
workflow_dispatch:
inputs:
version:
description: 'Version to publish (e.g., 3.6.0)'
required: true
type: string

env:
VERSION: ${{ github.event.inputs.version }}
Comment on lines +11 to +12

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

And then ~L34–38: Publish does not validate the version input

What the code does: $VERSION is taken from workflow_dispatch with no format check (Prepare has one). It is interpolated into grep -E "^## $VERSION\b".

What the spec says: Publish input is “Version to publish (e.g., 3.6.0).” Prepare already defines the allowed format.

Why it conflicts: An unvalidated value is an ERE on CHANGELOG, so the ready-gate can match the wrong header. [caused by change]

Suggested action: The author should apply the same version-format gate on Publish before grep or gh/npm.


permissions:
contents: write
id-token: write

jobs:
publish-release:
runs-on: ubuntu-latest
environment: npm
steps:
- uses: actions/checkout@v4

- name: Verify release is ready
run: |
if ! grep -qF "## $VERSION" CHANGELOG.md; then
echo "::error::CHANGELOG.md has no entry for $VERSION. Merge the prepare-release PR to master before running this workflow."
exit 1
Comment on lines +34 to +38

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Plus line 56/57. Publish does not verify that master HEAD is the version being published

What the code does: “Verify release is ready” is only grep -qE "^## $VERSION\b" CHANGELOG.md. Then npm publish --provenance publishes whatever package.json on master currently is. There is no check that package.json / src/itblBuildInfo.ts equal $VERSION. ## 3.1.0 is already on master today, so Publish 3.1.0 would pass the grep while npm publish would ship 3.1.0 or a newer prepared version depending on what is in package.json. gh release edit "$VERSION" --latest then operates on the GitHub release named by the input, not by the npm package version.

What the spec says: “Verifies the prepare-release PR has been merged (checks CHANGELOG on master)” and “Publishes to npm (@iterable/react-native-sdk)”. The role of that gate is to prove this version was prepared and merged, then publish that version.

Why it conflicts: A historical ## X.Y.Z header always remains in CHANGELOG. The grep cannot tell “3.2.0 was just merged” from “3.1.0 shipped last quarter.” npm and GitHub can then diverge (wrong GitHub release marked Latest, or npm publishing a different version than the input). [caused by change]

Suggested action: The author should make the ready-gate prove identity at master HEAD: changelog header and package.json / itblBuildInfo.ts equal the input version, and refuse when they don’t. Historical headers must not count as “prepare PR merged.”

fi
Comment thread
jferrao-itrbl marked this conversation as resolved.

- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'yarn'
registry-url: 'https://registry.npmjs.org'

- name: Update npm for OIDC support
run: npm install -g npm@latest

- run: yarn install --frozen-lockfile

- run: yarn test --maxWorkers=2

- run: yarn prepare

- name: Publish to npm
run: npm publish --provenance

- name: Publish draft GitHub release and tag main
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release edit "$VERSION" \
--draft=false \
--target "$(git rev-parse HEAD)" \
--latest
Comment on lines +56 to +66

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

npm publish is not retry-safe relative to the GitHub release step

What the code does: npm publish --provenance runs, then gh release edit publishes the draft and tags HEAD. Spec lists draft/tag then npm. If npm succeeds and gh release edit fails (no draft, auth, etc.), a rerun dies on “cannot publish over previously published versions” and never reaches the GitHub step.

What the spec says: “Publishes the draft release and creates the tag on master at this moment” then “Publishes to npm.”

Why it conflicts: The happy path can work, but a partial failure leaves the package on npm with no tag/release and no way to finish via this workflow. Android PR #1090 uses the same distro-then-GitHub order, so this may be the team’s real sequence — the retry hole remains. [caused by change]

Suggested action: The author should make Publish finish (or skip) each step idempotently so a retry can complete the GitHub release after npm already succeeded, and align the PR body with the actual order.


- name: Slack notification
run: |
release_url="https://github.com/${{ github.repository }}/releases/tag/$VERSION"
payload=$(jq -n \
--arg text ":package: *React Native SDK ${VERSION}* has been released. <${release_url}|View release notes>." \
'{"text": $text}')
curl -sS -X POST -H 'Content-type: application/json' --data "$payload" "${{ secrets.SLACK_WEBHOOK }}"

- name: Slack failure notification
if: failure()
run: |
run_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }}"
payload=$(jq -n \
--arg text ":alert: React Native SDK release ${VERSION} failed (attempt ${{ github.run_attempt }}). Run: ${run_url}" \
'{"text": $text}')
curl -sS -X POST -H 'Content-type: application/json' --data "$payload" "${{ secrets.SLACK_WEBHOOK }}"
Loading