Skip to content

Commit

Permalink
feat: create releases where PATCH doesn't have to match react-native (#…
Browse files Browse the repository at this point in the history
…43)

This feature needs to be released with react-native-community/cli#2475,
which decouples the 1:1 release model we have for templates and
react-native.

Switching users to this is going to be difficult, and should only be
rolled asap before 0.76. If we have to release a template fix, then only
users with the latest CLI will be able to use that and subsequent
versions.

I'm not sure of how to clearly communicate that to users.

- Added tests
- Set dry_run to default
  • Loading branch information
blakef authored Sep 8, 2024
1 parent 2b2aac9 commit b46b99f
Show file tree
Hide file tree
Showing 6 changed files with 2,244 additions and 15 deletions.
32 changes: 19 additions & 13 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ on:
workflow_dispatch:
inputs:
version:
description: "The version of the template we want to release. For example 0.75.0-rc.0"
description: "The version of the react-native we the template to use in this release. For example 0.75.0-rc.0"
required: true
type: string
is_latest_on_npm:
description: "Whether we want to tag this template release as `latest` on NPM"
required: true
type: boolean
default: false
dry_run:
description: "Run without making persistent changes to git or npm"
type: boolean
default: true

jobs:
publish_template:
Expand All @@ -30,35 +34,37 @@ jobs:
with:
node-version: 18
registry-url: 'https://registry.npmjs.org'
- name: Determine new template version
run: echo "VERSION=$(./scripts/bumpedTemplateVersion.sh \"${{ inputs.version }}\")" >> $GITHUB_ENV
- name: Update versions to input one
run: node ./scripts/updateTemplateVersion.js "${{ inputs.version }}"
run: node ./scripts/updateTemplateVersion.js $VERSION
- name: Update template/package.json to nightly react-native + @react-native
run: node ./scripts/updateReactNativeVersion.js "${{ inputs.version }}"
- name: Create corresponding commit & git tag
run: |
VERSION="${{ inputs.version }}"
git config --global user.name 'React Native Bot'
git config --global user.email '[email protected]'
git commit -am "Bumping template to $VERSION"
git push
git tag $VERSION
git push --tags
GIT=$([ "${{ inputs.dry_run }}" = "true" ] && "echo git" || "git";
$GIT config --global user.name 'React Native Bot'
$GIT config --global user.email '[email protected]'
$GIT commit -am "Bumping template to $VERSION"
$GIT push
$GIT tag $VERSION
$GIT push --tags
- name: Publish NPM
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Set NPM tags
run: |
VERSION="${{ inputs.version }}"
NPM=$([ "${{ inputs.dry_run }}" = "true" ] && "echo npm" || "npm";
IS_LATEST_ON_NPM="${{ inputs.is_latest_on_npm }}"
if [[ "$IS_LATEST_ON_NPM" == "true" ]]; then
npm dist-tag add @react-native-community/template@$VERSION latest
$NPM dist-tag add @react-native-community/template@$VERSION latest
fi
if [[ "$VERSION" == *"rc"* ]]; then
npm dist-tag add @react-native-community/template@$VERSION next
$NPM dist-tag add @react-native-community/template@$VERSION next
fi
if [[ "$GITHUB_REF_NAME" == *"-stable" ]]; then
npm dist-tag add @react-native-community/template@$VERSION $GITHUB_REF_NAME
$NPM dist-tag add @react-native-community/template@$VERSION $GITHUB_REF_NAME
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
9 changes: 9 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/** @type {import('jest').Config} */
const config = {
coverageProvider: "v8",
testMatch: [
"**/__tests__/*.js",
],
};

module.exports = config;
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@
"publishConfig": {
"access": "public"
},
"scripts": {},
"scripts": {
"test": "jest"
},
"type": "commonjs",
"files": [
"template/*",
"template.config.js"
],
"dependencies": {},
"devDependencies": {},
"devDependencies": {
"jest": "^29.7.0",
"semver": "^7.6.3"
},
"homepage": "https://github.com/react-native-community/template/tree/main",
"repository": {
"type": "git",
Expand Down
30 changes: 30 additions & 0 deletions scripts/__tests__/bumpTemplateVersion-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const {execSync} = require('child_process');
const semver = require('semver');

function run(version) {
return execSync(`./bumpedTemplateVersion.sh ${version}`, { cwd: 'scripts', stdio: ['ignore', 'pipe', 'ignore'] }).toString().trim();
}

describe('bumpTemplateVersion.sh', () => {

it('nightlies stay the same', () => {
expect(run('0.75.0-nightly-20240606-4324f0874')).toEqual('0.75.0-nightly-20240606-4324f0874');
});

it('release candidates appended with a sha', () => {
expect(run('0.74.0-rc.3')).toMatch(/0\.74\.0-rc\.3-.+/);
});

it('assumed it is the first version when no matching MAJOR.MINOR', () => {
const versionShouldNeverExist = '1111.0.1';
expect(run(versionShouldNeverExist)).toEqual('1111.0.0');
});

it('bumps the patch if a version of the template already exists', async () => {
// This sucks I know:
const {version} = await fetch('https://registry.npmjs.com/@react-native-community/template/latest').then(resp => resp.json());
const {major, minor, patch} = semver.parse(version);
expect(run(`${major}.${minor}.${patch}`)).toEqual(`${major}.${minor}.${patch+1}`);
});

});
50 changes: 50 additions & 0 deletions scripts/bumpedTemplateVersion.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/bash

# What this does:
# 1. Take the version of react, use the MAJOR.MINOR
# - /nightly/ -> MAJOR.MINOR.PATCH-nightly-YYYYNN-HASH
# - /-rc.N/ -> MAJOR.MINOR.PATCH-rc.N-HASH
# - ELSE: continue
# 2. Look for the latest version of the template with that MAJOR.MINOR
# - No version -> then set to MAJOR.MINOR.0
# - MAJOR.MINOR.PATCH -> MAJOR.MINOR.PATCH+1

log() {
echo "$@" >&2
}

if [[ $# != 1 ]]; then
log "USAGE: bumpTemplateVersion.sh <react native version>"
exit 1
fi

if [[ $1 =~ -rc\.[0-9]+ ]]; then
log "Release candidate"
# Append a sha, so if we need to re-release for a RC we don't conflict
echo $1-$(git rev-parse --short HEAD)
exit 0
fi

if [[ $1 =~ -nightly- ]]; then
log "Nightly candidate"
# Once a day, we're not going to get conflicts using the given nightly tag
echo $1
exit 0
fi

# Find current version of template that matches this version of react-native.
if [[ $1 =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then
MAJOR_MINOR=$(awk -F'.' '{ print $1"."$2 }' <<< $1)
CURRENT_VERSION=$(npm show --json "@react-native-community/template@^$MAJOR_MINOR")
if [ $? -ne 0 ]; then
echo "$MAJOR_MINOR.0";
exit 0;
fi
# Bump PATCH
PUBLISHED=$(jq -r 'last | .version' <<< $CURRENT_VERSION | awk -F'.' '{ print $1"."$2"."($3+1) }')
echo $PUBLISHED;
exit 0
fi

log "Unknown type of release: $RN_VERSION"
exit 1
Loading

0 comments on commit b46b99f

Please sign in to comment.