diff --git a/.ado/apple-pr.yml b/.ado/apple-pr.yml index b67226025c41b4..c8671f8441ea63 100644 --- a/.ado/apple-pr.yml +++ b/.ado/apple-pr.yml @@ -26,7 +26,6 @@ stages: dependsOn: [] jobs: - template: /.ado/jobs/test-javascript.yml@self - - template: /.ado/jobs/npm-publish-dry-run.yml@self # https://github.com/microsoft/react-native-macos/issues/2344 # The Verdaccio server consistently hangs on creation, which is required for the integration tests diff --git a/.ado/jobs/npm-publish-dry-run.yml b/.ado/jobs/npm-publish-dry-run.yml deleted file mode 100644 index 2fa1df7717cead..00000000000000 --- a/.ado/jobs/npm-publish-dry-run.yml +++ /dev/null @@ -1,10 +0,0 @@ -jobs: -- job: NPMPublishDryRun - displayName: NPM Publish Dry Run - pool: - vmImage: $(VmImageApple) - timeoutInMinutes: 60 - cancelTimeoutInMinutes: 5 - steps: - - template: /.ado/templates/npm-publish-steps.yml@self - diff --git a/.ado/jobs/npm-publish.yml b/.ado/jobs/npm-publish.yml index 6e879f0feb38b3..c43af09e3f843b 100644 --- a/.ado/jobs/npm-publish.yml +++ b/.ado/jobs/npm-publish.yml @@ -16,4 +16,57 @@ jobs: targetPath: $(System.DefaultWorkingDirectory) artifactName: github-npm-js-publish steps: - - template: /.ado/templates/npm-publish-steps.yml@self \ No newline at end of file + - checkout: self + clean: true + fetchFilter: blob:none + persistCredentials: true + + - template: /.ado/templates/configure-git.yml@self + + - script: | + PUBLISH_TAG=$(jq -r '.release.version.generatorOptions.currentVersionResolverMetadata.tag' nx.json) + echo "##vso[task.setvariable variable=publishTag]$PUBLISH_TAG" + echo "Using publish tag from nx.json: $PUBLISH_TAG" + displayName: Read publish tag from nx.json + + - script: | + yarn install + displayName: Install npm dependencies + + - script: | + node .ado/scripts/prepublish-check.mjs --verbose --skip-auth --tag $(publishTag) + displayName: Verify release config + + - script: | + echo Target branch: $(System.PullRequest.TargetBranch) + yarn nx release --dry-run --verbose + displayName: Version and publish packages (dry run) + condition: and(succeeded(), ne(variables['publish_react_native_macos'], '1')) + + # Disable Nightly publishing on the main branch + - ${{ if endsWith(variables['Build.SourceBranchName'], '-stable') }}: + - script: | + echo "//registry.npmjs.org/:_authToken=$(npmAuthToken)" > ~/.npmrc + node .ado/scripts/prepublish-check.mjs --verbose --tag $(publishTag) + displayName: Set and validate npm auth + condition: and(succeeded(), eq(variables['publish_react_native_macos'], '1')) + + - script: | + git switch $(Build.SourceBranchName) + yarn nx release --skip-publish --verbose + env: + GITHUB_TOKEN: $(githubAuthToken) + displayName: Version Packages and Github Release + condition: and(succeeded(), eq(variables['publish_react_native_macos'], '1')) + + - script: | + if [[ -f .rnm-publish ]]; then + yarn nx release publish --tag ${{ parameters['publishTag'] }} --excludeTaskDependencies + fi + displayName: Publish packages + condition: and(succeeded(), eq(variables['publish_react_native_macos'], '1')) + + - script: | + rm -f ~/.npmrc + displayName: Remove npmrc if it exists + condition: always() diff --git a/.ado/scripts/prepublish-check.mjs b/.ado/scripts/prepublish-check.mjs index 4deb49f1fc6212..822691b4813964 100644 --- a/.ado/scripts/prepublish-check.mjs +++ b/.ado/scripts/prepublish-check.mjs @@ -3,7 +3,6 @@ import { spawnSync } from "node:child_process"; import * as fs from "node:fs"; import * as util from "node:util"; -const ADO_PUBLISH_PIPELINE = ".ado/templates/npm-publish-steps.yml"; const NX_CONFIG_FILE = "nx.json"; const NPM_DEFEAULT_REGISTRY = "https://registry.npmjs.org/" @@ -139,9 +138,20 @@ function versionToNumber(version) { * @returns {string | undefined} */ function getTargetBranch() { - // https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services - const adoTargetBranchName = process.env["SYSTEM_PULLREQUEST_TARGETBRANCH"]; - return adoTargetBranchName?.replace(/^refs\/heads\//, ""); + // Azure Pipelines + if (process.env["TF_BUILD"] === "True") { + // https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services + const targetBranch = process.env["SYSTEM_PULLREQUEST_TARGETBRANCH"]; + return targetBranch?.replace(/^refs\/heads\//, ""); + } + + // GitHub Actions + if (process.env["GITHUB_ACTIONS"] === "true") { + // https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables + return process.env["GITHUB_BASE_REF"]; + } + + return undefined; } /** @@ -151,15 +161,32 @@ function getTargetBranch() { * @returns {string} */ function getCurrentBranch(options) { - const adoTargetBranchName = getTargetBranch(); - if (adoTargetBranchName) { - return adoTargetBranchName; + const targetBranch = getTargetBranch(); + if (targetBranch) { + return targetBranch; } - // 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\//, ""); + // Azure DevOps Pipelines + if (process.env["TF_BUILD"] === "True") { + // https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services + const sourceBranch = process.env["BUILD_SOURCEBRANCHNAME"]; + if (sourceBranch) { + return sourceBranch.replace(/^refs\/heads\//, ""); + } + } + + // GitHub Actions + if (process.env["GITHUB_ACTIONS"] === "true") { + // https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables + const headRef = process.env["GITHUB_HEAD_REF"]; + if (headRef) { + return headRef; // For pull requests + } + + const ref = process.env["GITHUB_REF"]; + if (ref) { + return ref.replace(/^refs\/heads\//, ""); // For push events + } } const { "mock-branch": mockBranch } = options; @@ -242,23 +269,6 @@ function getTagForStableBranch(branch, { tag }, log) { return { npmTag: NPM_TAG_NEXT, prerelease: "rc" }; } -/** - * @param {string} file - * @param {string} tag - * @returns {void} - */ -function verifyPublishPipeline(file, tag) { - const data = fs.readFileSync(file, { encoding: "utf-8" }); - const m = data.match(/publishTag: '(latest|next|nightly|v\d+\.\d+-stable)'/); - if (!m) { - throw new Error(`${file}: Could not find npm publish tag`); - } - - if (m[1] !== tag) { - throw new Error(`${file}: 'publishTag' must be set to '${tag}'`); - } -} - /** * Verifies the configuration and enables publishing on CI. * @param {NxConfig} config @@ -325,8 +335,6 @@ function enablePublishing(config, currentBranch, { npmTag: tag, prerelease, isNe verifyNpmAuth(); } - verifyPublishPipeline(ADO_PUBLISH_PIPELINE, tag); - // Don't enable publishing in PRs if (!getTargetBranch()) { enablePublishingOnAzurePipelines(); diff --git a/.ado/templates/npm-publish-steps.yml b/.ado/templates/npm-publish-steps.yml deleted file mode 100644 index 61ccda2726dc14..00000000000000 --- a/.ado/templates/npm-publish-steps.yml +++ /dev/null @@ -1,53 +0,0 @@ -parameters: - # If this is a new stable branch, change `publishTag` to `latest` when going stable - publishTag: 'nightly' - -steps: - - checkout: self - clean: true - fetchFilter: blob:none - persistCredentials: true - - - template: /.ado/templates/configure-git.yml@self - - - script: | - yarn install - displayName: Install npm dependencies - - - script: | - node .ado/scripts/prepublish-check.mjs --verbose --skip-auth --tag ${{ parameters['publishTag'] }} - displayName: Verify release config - - - script: | - echo Target branch: $(System.PullRequest.TargetBranch) - yarn nx release --dry-run --verbose - displayName: Version and publish packages (dry run) - condition: and(succeeded(), ne(variables['publish_react_native_macos'], '1')) - - # Disable Nightly publishing on the main branch - - ${{ if endsWith(variables['Build.SourceBranchName'], '-stable') }}: - - script: | - echo "//registry.npmjs.org/:_authToken=$(npmAuthToken)" > ~/.npmrc - node .ado/scripts/prepublish-check.mjs --verbose --tag ${{ parameters['publishTag'] }} - displayName: Set and validate npm auth - condition: and(succeeded(), eq(variables['publish_react_native_macos'], '1')) - - - script: | - git switch $(Build.SourceBranchName) - yarn nx release --skip-publish --verbose - env: - GITHUB_TOKEN: $(githubAuthToken) - displayName: Version Packages and Github Release - condition: and(succeeded(), eq(variables['publish_react_native_macos'], '1')) - - - script: | - if [[ -f .rnm-publish ]]; then - yarn nx release publish --tag ${{ parameters['publishTag'] }} --excludeTaskDependencies - fi - displayName: Publish packages - condition: and(succeeded(), eq(variables['publish_react_native_macos'], '1')) - - - script: | - rm -f ~/.npmrc - displayName: Remove npmrc if it exists - condition: always() diff --git a/.github/workflows/microsoft-pr.yml b/.github/workflows/microsoft-pr.yml index de2bbc40d0ae7f..1719fc714563f1 100644 --- a/.github/workflows/microsoft-pr.yml +++ b/.github/workflows/microsoft-pr.yml @@ -3,7 +3,7 @@ name: PR on: pull_request: types: [opened, synchronize, edited] - branches: [ "main" ] + branches: [ "main", "*-stable", "release/*" ] concurrency: # Ensure single build of a pull request. `main` should not be affected. @@ -11,7 +11,7 @@ concurrency: cancel-in-progress: true jobs: - lint-commit: + lint-title: name: "Lint PR title" permissions: {} runs-on: ubuntu-latest @@ -34,5 +34,38 @@ jobs: build-website: name: "Build the website" permissions: {} + if: github.base_ref == 'main' uses: ./.github/workflows/microsoft-build-website.yml + npm-publish-dry-run: + name: "NPM Publish (Dry Run)" + permissions: {} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + filter: blob:none + fetch-depth: 0 + - uses: actions/setup-node@v4 + with: + node-version: '22' + - name: Read publish tag from nx.json + id: config + run: | + PUBLISH_TAG=$(jq -r '.release.version.generatorOptions.currentVersionResolverMetadata.tag' nx.json) + echo "publishTag=$PUBLISH_TAG" >> $GITHUB_OUTPUT + echo "Using publish tag from nx.json: $PUBLISH_TAG" + - name: Configure git + run: | + git config --global user.email "53619745+rnbot@users.noreply.github.com" + git config --global user.name "React-Native Bot" + git remote set-url origin https://rnbot:${{ secrets.GITHUB_TOKEN }}@github.com/microsoft/react-native-macos + - name: Install dependencies + run: yarn + - name: Verify release config + run: | + node .ado/scripts/prepublish-check.mjs --verbose --skip-auth --tag ${{ steps.config.outputs.publishTag }} + - name: Version and publish packages (dry run) + run: | + echo "Target branch: ${{ github.base_ref }}" + yarn nx release --dry-run --verbose diff --git a/docs_archive/Releases.md b/docs_archive/Releases.md index 80cb81b609ea4a..c70a7a795be474 100644 --- a/docs_archive/Releases.md +++ b/docs_archive/Releases.md @@ -72,13 +72,7 @@ git push -u origin HEAD ## Marking a release candidate stable -Prepare the publish pipeline: - -```sh -sed -i '' "s/publishTag: 'next'/publishTag: 'latest'/" .ado/templates/npm-publish-steps.yml -``` - -Update the release configuration: +Prepare the release configuration: ```sh node .ado/scripts/prepublish-check.mjs --tag latest --update