Skip to content
Merged
Show file tree
Hide file tree
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
25 changes: 21 additions & 4 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ Once merged, run the [Release package workflow](../../actions/workflows/release.

1. Select `iOS` as the platform.
2. Enter the expected version. The workflow reads the SDK version from the checked-in files and fails if the typed version does not match.
3. Leave `dry-run` enabled first to review the release plan.
4. Rerun with `dry-run` disabled. By default this creates a draft GitHub Release with the bare semver tag (e.g. `3.8.1`) for human review.
3. Select `Dry run` first to review the release plan without creating a release.
4. Rerun with `Draft release` to create a draft GitHub Release with the bare semver tag (e.g. `3.8.1`) for human review.
5. Publish the draft release when ready. Publishing the draft kicks off the [Swift publish workflow](../../actions/workflows/swift-publish.yml), which publishes the new version to CocoaPods.

---
Expand Down Expand Up @@ -174,8 +174,8 @@ Once merged, run the [Release package workflow](../../actions/workflows/release.

1. Select `Android` as the platform.
2. Enter the expected version. The workflow reads the SDK version from `platforms/android/lib/build.gradle` and fails if the typed version does not match.
3. Leave `dry-run` enabled first to review the release plan.
4. Rerun with `dry-run` disabled. By default this creates a draft GitHub Release with the `android/`-prefixed tag (e.g. `android/3.0.1`) for human review.
3. Select `Dry run` first to review the release plan without creating a release.
4. Rerun with `Draft release` to create a draft GitHub Release with the `android/`-prefixed tag (e.g. `android/3.0.1`) for human review.
5. Publish the draft release when ready. Publishing the draft kicks off the [Android publish workflow](../../actions/workflows/android-publish.yml). **A manual approval by a maintainer is required before publication to Maven Central.**

---
Expand Down Expand Up @@ -208,3 +208,20 @@ If your change intentionally modifies the public API:
3. Commit the updated `.api.md` file in the same PR.

If you did *not* intend to change public API and `api:check` is failing, the diff shows what your change inadvertently affected — treat it as a signal that something in your PR has consumer-visible impact.

### Releasing a new React Native version

Open a pull request with the following changes:

1. Bump the `version` in `platforms/react-native/modules/@shopify/checkout-kit-react-native/package.json`.
2. Add an entry to the React Native changelog.

Supported release versions are `X.Y.Z` and prerelease versions are `X.Y.Z-{alpha|beta|rc}.N`.

Once merged, run the [Release package workflow](../../actions/workflows/release.yml):

1. Select `React Native` as the platform.
2. Enter the expected version. The workflow reads the SDK version from `platforms/react-native/modules/@shopify/checkout-kit-react-native/package.json` and fails if the typed version does not match.
3. Select `Dry run` first to review the release plan without creating a release.
4. From the dry-run job summary, copy the generated `gh workflow run` command to create a `Draft release` without retyping the validated version. Running it creates a draft GitHub Release with the `react-native/`-prefixed tag (e.g. `react-native/4.0.1`) for human review.
5. Publish the draft release when ready. Publishing the draft kicks off the [React Native publish workflow](../../actions/workflows/rn-publish.yml), which publishes `@shopify/checkout-kit-react-native` to npm.
21 changes: 21 additions & 0 deletions .github/scripts/package-json-version
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -euo pipefail

file="${1:-}"

if [ -z "$file" ]; then
echo "::error::Usage: package-json-version <package.json>" >&2
exit 2
fi

if [ ! -f "$file" ]; then
echo "::error file=$file::Version source file does not exist." >&2
exit 1
fi

if ! version=$(jq -er '.version | strings | select(length > 0)' "$file"); then
echo "::error file=$file::Could not extract version." >&2
exit 1
fi

printf '%s' "$version"
24 changes: 22 additions & 2 deletions .github/scripts/validate-release-version
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Usage: validate-release-version <platform> [expected-version] [expected-tag]
Validates the selected SDK's checked-in version declarations, optional user
version input, optional git tag, and prints GitHub Actions outputs to stdout.

Platforms: iOS, Android
Platforms: iOS, Android, React Native
USAGE
}

Expand Down Expand Up @@ -42,6 +42,12 @@ extract_first_match() {
printf '%s\n' "$value"
}

json_version() {
local file="$1"

.github/scripts/package-json-version "$file"
}

check_same_version() {
local expected="$1"
local file="$2"
Expand Down Expand Up @@ -84,8 +90,19 @@ case "$PLATFORM_INPUT" in
VERSION=$(extract_first_match "$ANDROID_VERSION_FILE" 's/^[[:space:]]*def[[:space:]]+versionName[[:space:]]*=[[:space:]]*"([^"]+)".*/\1/p')
;;

"React Native"|react-native|ReactNative|rn|RN)
PLATFORM="react-native"
DISPLAY_PLATFORM="React Native"
RELEASE_TITLE_PREFIX="React Native"
TAG_PREFIX="react-native/"
PUBLISH_WORKFLOW="rn-publish.yml"

RN_PACKAGE_FILE="platforms/react-native/modules/@shopify/checkout-kit-react-native/package.json"
VERSION=$(json_version "$RN_PACKAGE_FILE")
;;

*)
echo "::error::Unsupported platform '$PLATFORM_INPUT'. Expected one of: iOS, Android." >&2
echo "::error::Unsupported platform '$PLATFORM_INPUT'. Expected one of: iOS, Android, React Native." >&2
exit 1
;;
esac
Expand All @@ -110,8 +127,10 @@ fi

if [[ "$VERSION" == *-* ]]; then
PRERELEASE="true"
NPM_TAG="next"
else
PRERELEASE="false"
NPM_TAG="latest"
fi

{
Expand All @@ -122,6 +141,7 @@ fi
echo "release_title=$RELEASE_TITLE"
echo "publish_workflow=$PUBLISH_WORKFLOW"
echo "prerelease=$PRERELEASE"
echo "npm_tag=$NPM_TAG"
}

echo "✓ ${DISPLAY_PLATFORM} version '$VERSION' validates and maps to tag '$TAG'." >&2
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ jobs:
- '.github/workflows/rn-build-ios.yml'
- '.github/workflows/rn-check-packed-files.yml'
- '.github/workflows/rn-lint.yml'
- '.github/workflows/rn-publish.yml'
- '.github/workflows/release.yml'
- '.github/scripts/package-json-version'
- '.github/scripts/validate-release-version'
- '.github/actions/setup/**'
- '.github/workflows/breaking-changes.yml'
- '.github/workflows/ci.yml'
web:
Expand Down
75 changes: 53 additions & 22 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ on:
options:
- iOS
- Android
- React Native
version:
description: Expected SDK version. Must match the checked-in SDK version for the selected platform.
required: true
type: string
dry-run:
description: Dry run
mode:
description: Release mode
required: false
type: boolean
default: true
draft:
description: Draft release
required: false
type: boolean
default: true
type: choice
default: Dry run
options:
- Dry run
- Draft release
- Production release

permissions:
contents: write
Expand Down Expand Up @@ -81,14 +81,13 @@ jobs:

- name: Print release plan
env:
DRY_RUN: ${{ inputs['dry-run'] && 'true' || 'false' }}
MODE: ${{ inputs.mode }}
DISPLAY_PLATFORM: ${{ steps.release.outputs.display_platform }}
VERSION: ${{ steps.release.outputs.version }}
TAG: ${{ steps.release.outputs.tag }}
RELEASE_TITLE: ${{ steps.release.outputs.release_title }}
PRERELEASE: ${{ steps.release.outputs.prerelease }}
PUBLISH_WORKFLOW: ${{ steps.release.outputs.publish_workflow }}
DRAFT: ${{ inputs.draft && 'true' || 'false' }}
run: |
set -euo pipefail
echo "Release plan:"
Expand All @@ -98,21 +97,25 @@ jobs:
echo " Title: ${RELEASE_TITLE}"
echo " Prerelease: ${PRERELEASE}"
echo " Publish workflow: ${PUBLISH_WORKFLOW}"
echo " Dry run: ${DRY_RUN}"
echo " Draft release: ${DRAFT}"
if [ "$DRY_RUN" = "false" ] && [ "$DRAFT" = "true" ]; then
echo " Mode: ${MODE}"
if [ "$MODE" = "Dry run" ]; then
echo " Release creation: skipped"
echo " Publish dispatch: skipped"
elif [ "$MODE" = "Draft release" ]; then
echo " Release creation: draft GitHub Release"
echo " Publish dispatch: skipped until the draft release is manually published"
elif [ "$DRY_RUN" = "false" ]; then
else
echo " Release creation: published GitHub Release"
echo " Publish dispatch: ${PUBLISH_WORKFLOW} will be dispatched after release creation"
fi

- name: Create GitHub Release
if: ${{ !inputs['dry-run'] }}
if: ${{ inputs.mode != 'Dry run' }}
env:
TAG: ${{ steps.release.outputs.tag }}
RELEASE_TITLE: ${{ steps.release.outputs.release_title }}
PRERELEASE: ${{ steps.release.outputs.prerelease }}
DRAFT: ${{ inputs.draft && 'true' || 'false' }}
DRAFT: ${{ inputs.mode == 'Draft release' && 'true' || 'false' }}
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
Expand All @@ -131,7 +134,7 @@ jobs:
gh release create "${args[@]}"

- name: Dispatch publish workflow
if: ${{ !inputs['dry-run'] && !inputs.draft }}
if: ${{ inputs.mode == 'Production release' }}
env:
TAG: ${{ steps.release.outputs.tag }}
PUBLISH_WORKFLOW: ${{ steps.release.outputs.publish_workflow }}
Expand All @@ -143,22 +146,50 @@ jobs:

- name: Summary
env:
DRY_RUN: ${{ inputs['dry-run'] && 'true' || 'false' }}
DRAFT: ${{ inputs.draft && 'true' || 'false' }}
MODE: ${{ inputs.mode }}
DISPLAY_PLATFORM: ${{ steps.release.outputs.display_platform }}
VERSION: ${{ steps.release.outputs.version }}
TAG: ${{ steps.release.outputs.tag }}
RELEASE_TITLE: ${{ steps.release.outputs.release_title }}
PUBLISH_WORKFLOW: ${{ steps.release.outputs.publish_workflow }}
REF_NAME: ${{ github.ref_name }}
PLATFORM: ${{ inputs.platform }}
run: |
set -euo pipefail

WORKFLOW_URL="https://github.com/${GITHUB_REPOSITORY}/actions/workflows/release.yml"

cat >> "$GITHUB_STEP_SUMMARY" <<SUMMARY
## Release plan

- Dry run: `${DRY_RUN}`
- Draft release: `${DRAFT}`
- Mode: \`${MODE}\`
- Platform: ${DISPLAY_PLATFORM}
- Version: ${VERSION}
- Tag: \`${TAG}\`
- Title: ${RELEASE_TITLE}
- Publish workflow: \`${PUBLISH_WORKFLOW}\`
SUMMARY

if [ "$MODE" = "Dry run" ]; then
cat >> "$GITHUB_STEP_SUMMARY" <<SUMMARY

## Continue to draft release

GitHub does not currently support pre-filled \`workflow_dispatch\`
form inputs via URL. To avoid retyping the validated version, run this
GitHub CLI command:

\`\`\`bash
gh workflow run release.yml \\
--repo "${GITHUB_REPOSITORY}" \\
--ref "${REF_NAME}" \\
-f platform="${PLATFORM}" \\
-f version="${VERSION}" \\
-f mode="Draft release"
\`\`\`

Or open the [Release package workflow](${WORKFLOW_URL}) and enter the
same values manually.
SUMMARY
echo "::notice::GitHub CLI draft release command written to the job summary."
fi
Loading
Loading