Skip to content

Commit

Permalink
chore: set up proper publishing pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
tido64 committed Nov 21, 2024
1 parent c952214 commit 77bc912
Show file tree
Hide file tree
Showing 16 changed files with 1,198 additions and 1,383 deletions.
4 changes: 1 addition & 3 deletions .ado/jobs/npm-publish-dry-run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,4 @@ jobs:
submodules: recursive # set to 'true' for a single level of submodules or 'recursive' to get submodules of submodules
persistCredentials: true # set to 'true' to leave the OAuth token in the Git config after the initial fetch

- template: /.ado/templates/apple-steps-publish.yml@self
parameters:
build_type: 'dry-run'
- template: /.ado/templates/npm-publish.yml@self
41 changes: 1 addition & 40 deletions .ado/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,46 +76,7 @@ extends:
submodules: recursive # set to 'true' for a single level of submodules or 'recursive' to get submodules of submodules
persistCredentials: true # set to 'true' to leave the OAuth token in the Git config after the initial fetch

# Setup the repo to be ready for release. This includes:
# - Autogenerating the next version number
# - Calling the approprate scripts that upstream React Native uses to prepare a release
# - Skipping the actual `git tag`, `git push`, and `npm publish steps as we do that here instead

- ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
- template: .ado/templates/apple-steps-publish.yml@self
parameters:
build_type: nightly
- ${{ elseif endsWith(variables['Build.SourceBranchName'], '-stable') }}:
- template: .ado/templates/apple-steps-publish.yml@self
parameters:
build_type: release
- ${{ else }}:
- task: CmdLine@2
displayName: Unknown branch, skipping publish
inputs:
script: |
echo "Skipping publish for branch $(Build.SourceBranchName)"
exit 1
# Set the NPM dist-tag and do the actual NPM publish

- bash: echo "##vso[task.setvariable variable=npmDistTag]latest"
displayName: Set dist-tag to latest
condition: eq(variables['Build.SourceBranchName'], variables.latestStableBranch)

- bash: echo "##vso[task.setvariable variable=npmDistTag]canary"
displayName: Set dist-tag to canary
condition: eq(variables['Build.SourceBranchName'], 'main')

- bash: echo "##vso[task.setvariable variable=npmDistTag]v${{variables['Build.SourceBranchName']}}"
displayName: Set dist-tag to v0.x-stable
condition: and(ne(variables['Build.SourceBranchName'], 'main'), ne(variables['Build.SourceBranchName'], variables.latestStableBranch))

- task: CmdLine@2
displayName: Actual NPM Publish
inputs:
script: |
npm publish ./packages/react-native --tag $(npmDistTag) --registry https://registry.npmjs.org/ --//registry.npmjs.org/:_authToken=$(npmAuthToken)
- template: /.ado/templates/npm-publish.yml@self

# Set the git tag and push the version update back to Github

Expand Down
155 changes: 155 additions & 0 deletions .ado/scripts/prepublish-check.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// @ts-check
import { spawnSync } from "node:child_process";
import * as fs from "node:fs";
import * as util from "node:util";

/**
* @typedef {typeof import("../../nx.json")} NxConfig
* @typedef {{ tag?: string }} Options
*/

/**
* Exports a variable, `publish_react_native_macos`, to signal that we want to
* enable publishing on Azure Pipelines.
*
* Note that pipelines need to read this variable separately and do the actual
* work to publish bits.
*/
function enablePublishingOnAzurePipelines() {
console.log(`##vso[task.setvariable variable=publish_react_native_macos]1`);
}

/**
* Loads Nx configuration.
* @returns {NxConfig}
*/
function loadNxConfig(configFile = "nx.json") {
const nx = fs.readFileSync(configFile, { encoding: "utf-8" });
return JSON.parse(nx);
}

/**
* Returns the currently checked out branch. Note that this function prefers
* predefined CI environment variables over local clone.
* @returns {string}
*/
function getCurrentBranch() {
// https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services
const adoSourceBranchName = process.env["BUILD_SOURCEBRANCHNAME"];
if (adoSourceBranchName) {
return adoSourceBranchName.replace(/^refs\/heads\//, "");
}

// Depending on how the repo was cloned, HEAD may not exist. We only use this
// method as fallback.
const { stdout } = spawnSync("git", ["rev-parse", "--abbrev-ref", "HEAD"]);
return stdout.toString().trim();
}

/**
* @param {string} branch
* @param {Options} options
* @returns {{ npmTag: string; prerelease?: string; }}
*/
function getStableTag(branch, { tag }) {
switch (tag) {
case "latest":
return { npmTag: tag };

case "next":
return { npmTag: tag, prerelease: "rc" };

default:
return { npmTag: "v" + branch };
}
}

/**
* Returns whether the given branch is considered main branch.
* @param {string} branch
*/
function isMainBranch(branch) {
// There is currently no good way to consistently get the main branch. We
// hardcode the value for now.
return branch === "main";
}

/**
* Returns whether the given branch is considered a stable branch.
* @param {string} branch
*/
function isStableBranch(branch) {
return /^\d+\.\d+-stable$/.test(branch);
}

/**
* Verifies the configuration and enables publishing on CI.
* @param {NxConfig} config
* @param {string} currentBranch
* @param {string} tag
* @param {string} [prerelease]
* @returns {asserts config is NxConfig["release"]}
*/
function enablePublishing({ defaultBase, release: config }, currentBranch, tag, prerelease) {
/** @type {string[]} */
const errors = [];

// `defaultBase` determines what we diff against when looking for tags or
// released version and must therefore be set to either the main branch or one
// of the stable branches.
if (currentBranch !== defaultBase) {
errors.push(`'defaultBase' must be set to '${currentBranch}'`);
}

// Determines whether we need to add "nightly" or "rc" to the version string.
const { currentVersionResolverMetadata, preid } = config.version.generatorOptions;
if (preid !== prerelease) {
errors.push(`'release.version.generatorOptions.preid' must be set to '${prerelease || ""}'`);
}

// What the published version should be tagged as e.g., "latest" or "nightly".
if (currentVersionResolverMetadata.tag !== tag) {
errors.push(`'release.version.generatorOptions.currentVersionResolverMetadata.tag' must be set to '${tag}'`);
}

if (errors.length > 0) {
for (const e of errors) {
console.error("❌", e);
}
throw new Error("Nx Release is not correctly configured for the current branch");
}

enablePublishingOnAzurePipelines();
}

/**
* @param {Options} options
*/
function main(options) {
const branch = getCurrentBranch();
if (!branch) {
throw new Error("Could not get current branch");
}

const config = loadNxConfig();
if (isMainBranch(branch)) {
enablePublishing(config, branch, "nightly", "nightly");
} else if (isStableBranch(branch)) {
const { npmTag, prerelease } = getStableTag(branch, options);
enablePublishing(config, branch, npmTag, prerelease);
}
}

const { values } = util.parseArgs({
args: process.argv.slice(2),
options: {
tag: {
type: "string",
default: "next",
},
},
strict: true,
allowNegative: true,
});

main(values);
11 changes: 3 additions & 8 deletions .ado/scripts/verdaccio.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,9 @@ case ${1-} in

"publish")
checkpoint=$(git rev-parse HEAD)
yarn set-version 1000.0.0-pr
git commit --all --message 'bump' --no-verify
packages=()
for json in $(yarn workspaces list --no-private --json); do
packages+=(--package $(node --print "JSON.parse('$json').name"))
done
npx beachball change --no-fetch --type patch --message 'bump for testing purposes' ${packages[@]}
npx beachball $* --no-push --registry $NPM_REGISTRY --yes --access public --no-generate-changelog
cp nx.test.json nx.json
yarn nx release version 1000.0.0
yarn nx release publish --registry $NPM_REGISTRY
git reset --hard $checkpoint
;;
esac
37 changes: 37 additions & 0 deletions .ado/templates/npm-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
parameters:
# If this is a new stable branch, change `publishTag` to `latest` when going stable
latestStableBranch: '0.76-stable'
publishTag: 'next'

steps:
- script: |
yarn install
displayName: Install npm dependencies
- script: |
node .ado/scripts/prepublish-check.mjs --tag nightly
displayName: Verify release config (nightly)
condition: ${{ eq(variables['Build.SourceBranch'], 'refs/heads/main') }}
- script: |
node .ado/scripts/prepublish-check.mjs --tag ${{ parameters['publishTag'] }}
displayName: Verify release config (latest)
condition: ${{ eq(variables['Build.SourceBranchName'], parameters['latestStableBranch']) }}
- script: |
node .ado/scripts/prepublish-check.mjs
displayName: Verify release config (stable)
condition: ${{ endsWith(variables['Build.SourceBranchName'], '-stable') }}
- script: |
yarn nx release --dry-run
displayName: Version and publish packages (dry run)
condition: ${{ ne(variables['publish_react_native_macos'], '1') }}
- script: |
#yarn nx release --yes
yarn nx release --dry-run
env:
NODE_AUTH_TOKEN: $(npmAuthToken)
displayName: Version and publish packages
condition: ${{ eq(variables['publish_react_native_macos'], '1') }}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,8 @@ vendor/
.ado/Brewfile.lock.json
.ado/verdaccio/htpasswd
.ado/verdaccio/storage/.verdaccio-db.json

# Nx
.nx/cache
.nx/workspace-data
# macOS]
29 changes: 29 additions & 0 deletions nx.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"defaultBase": "main",
"targetDefaults": {
"build": {
"dependsOn": ["^build"]
}
},
"release": {
"changelog": {
"projectChangelogs": false,
"workspaceChangelog": false
},
"projects": ["packages/react-native", "packages/virtualized-lists"],
"projectsRelationship": "independent",
"versionPlans": true,
"version": {
"generatorOptions": {
"currentVersionResolver": "registry",
"currentVersionResolverMetadata": {
"tag": "nightly"
},
"fallbackCurrentVersionResolver": "disk",
"preid": "nightly",
"skipLockFileUpdate": true
}
}
}
}
27 changes: 27 additions & 0 deletions nx.test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"defaultBase": "main",
"targetDefaults": {
"build": {
"dependsOn": ["^build"]
}
},
"release": {
"changelog": {
"projectChangelogs": false,
"workspaceChangelog": false
},
"projects": ["packages/*"],
"projectsRelationship": "fixed",
"versionPlans": true,
"version": {
"generatorOptions": {
"currentVersionResolver": "disk",
"currentVersionResolverMetadata": {
"tag": "latest"
},
"skipLockFileUpdate": true
}
}
}
}
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"@babel/preset-flow": "^7.24.7",
"@definitelytyped/dtslint": "^0.0.127",
"@jest/create-cache-key-function": "^29.6.3",
"@nx/js": "~20.0.0",
"@pkgjs/parseargs": "^0.11.0",
"@react-native/metro-babel-transformer": "0.76.0-main",
"@react-native/metro-config": "0.76.0-main",
Expand Down Expand Up @@ -96,6 +97,7 @@
"mkdirp": "^0.5.1",
"node-fetch": "^2.2.0",
"nullthrows": "^1.1.1",
"nx": "~20.0.0",
"prettier": "2.8.8",
"prettier-plugin-hermes-parser": "0.23.1",
"react": "19.0.0-rc-fb9a90fa48-20240614",
Expand All @@ -107,9 +109,6 @@
"typescript": "5.0.4",
"ws": "^6.2.3"
},
"beachball": {
"shouldPublish": false
},
"resolutions": {
"react-is": "19.0.0-rc-fb9a90fa48-20240614",
"@grpc/proto-loader": "^0.7.8",
Expand Down
3 changes: 0 additions & 3 deletions packages/babel-plugin-codegen/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,5 @@
},
"devDependencies": {
"@babel/core": "^7.25.2"
},
"beachball": {
"shouldPublish": false
}
}
3 changes: 0 additions & 3 deletions packages/community-cli-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,5 @@
},
"engines": {
"node": ">=18"
},
"beachball": {
"shouldPublish": false
}
}
3 changes: 0 additions & 3 deletions packages/react-native-codegen/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@
"nullthrows": "^1.1.1",
"yargs": "^17.6.2"
},
"beachball": {
"shouldPublish": false
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
Expand Down
Loading

0 comments on commit 77bc912

Please sign in to comment.