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
46 changes: 44 additions & 2 deletions common/config/azure-pipelines/npm-post-publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ resources:
- pipeline: esrpPublishRushstack
source: 'rushstack-esrp-publish'
project: GitHubProjectsPublish
branch: refs/heads/main
trigger:
enabled: true
branches:
Expand All @@ -28,6 +29,7 @@ resources:
- pipeline: esrpPublishRush
source: 'rushstack-esrp-publish-rush'
project: GitHubProjectsPublish
branch: refs/heads/main
trigger:
enabled: true
branches:
Expand Down Expand Up @@ -115,12 +117,52 @@ extends:
--verbose
DisplayName: 'Rush Build (repo-toolbox)'

# Query the public feed directly to bypass propagation latency in the private feed.
# Use the versions recorded during publishing to avoid propagation latency in the package feeds.
- bash: |
set -e

triggering_alias="$(resources.triggeringAlias)"
rushstack_pipeline_id="$(resources.pipeline.esrpPublishRushstack.pipelineID)"
rushstack_run_id="$(resources.pipeline.esrpPublishRushstack.runID)"
rush_pipeline_id="$(resources.pipeline.esrpPublishRush.pipelineID)"
rush_run_id="$(resources.pipeline.esrpPublishRush.runID)"

if [[ "$triggering_alias" == "esrpPublishRushstack" ]]; then
pipeline_id="$rushstack_pipeline_id"
run_id="$rushstack_run_id"
elif [[ "$triggering_alias" == "esrpPublishRush" ]]; then
pipeline_id="$rush_pipeline_id"
run_id="$rush_run_id"
# If this pipeline was not resource-triggered, use whichever publishing pipeline ran latest.
elif (( rushstack_run_id > rush_run_id )); then
pipeline_id="$rushstack_pipeline_id"
run_id="$rushstack_run_id"
else
pipeline_id="$rush_pipeline_id"
run_id="$rush_run_id"
fi

echo "Using publishing pipeline $pipeline_id, run $run_id (trigger: ${triggering_alias:-manual})"
echo "##vso[task.setvariable variable=PublishingPipelineId]$pipeline_id"
echo "##vso[task.setvariable variable=PublishingRunId]$run_id"
displayName: 'Select publishing pipeline run'

- task: DownloadPipelineArtifact@2
displayName: 'Download published package versions'
inputs:
source: specific
project: GitHubProjectsPublish
pipeline: $(PublishingPipelineId)
runVersion: specific
runId: $(PublishingRunId)
artifact: published-versions
path: $(Pipeline.Workspace)/published-versions

- template: /common/config/azure-pipelines/templates/run-repo-toolbox.yaml@self
parameters:
Arguments: >
bump-decoupled-local-dependencies
--feed-url https://registry.npmjs.org/
--published-versions-path "$(Pipeline.Workspace)/published-versions/published-versions.json"
DisplayName: 'Bump decoupled local dependencies'

# If Rush itself was updated by bump-decoupled-local-dependencies, we need to bootstrap
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.

import * as path from 'node:path';
import type { ChildProcess } from 'node:child_process';

import { Async, Executable, FileSystem, type FolderItem, JsonFile } from '@rushstack/node-core-library';
Expand All @@ -12,8 +13,15 @@ import { CommandLineAction, type CommandLineStringParameter } from '@rushstack/t
async function _getLatestPublishedVersionAsync(
terminal: ITerminal,
packageName: string,
publishedVersions: Record<string, string> | undefined,
feedUrl: string | undefined
): Promise<string> {
const recordedVersion: string | undefined = publishedVersions?.[packageName];
if (recordedVersion) {
terminal.writeLine(`Found version "${recordedVersion}" for "${packageName}" in published versions file`);
return recordedVersion;
}

const npmArgs: string[] = ['view', packageName, 'version'];
if (feedUrl) {
npmArgs.push('--registry', feedUrl);
Expand All @@ -22,11 +30,20 @@ async function _getLatestPublishedVersionAsync(
const childProcess: ChildProcess = Executable.spawn('npm', npmArgs, {
stdio: ['ignore', 'pipe', 'pipe']
});
const { stdout: version } = await Executable.waitForExitAsync(childProcess, {
encoding: 'utf-8',
throwOnNonZeroExitCode: true,
throwOnSignal: true
const {
stdout: version,
exitCode,
signal,
stderr
} = await Executable.waitForExitAsync(childProcess, {
encoding: 'utf-8'
});
if (exitCode !== 0 || signal) {
throw new Error(
`Failed to get latest published version for "${packageName}". Exit code: ${exitCode}, Signal: ${signal}, Stderr: ${stderr}`
);
}

terminal.writeLine(`Found version "${version}" for "${packageName}"`);
return version;
}
Expand All @@ -40,6 +57,7 @@ interface IProjectLike {

export class BumpDecoupledLocalDependencies extends CommandLineAction {
readonly #feedUrlParameter: CommandLineStringParameter;
readonly #publishedVersionsPathParameter: CommandLineStringParameter;
readonly #terminal: ITerminal;

public constructor(terminal: ITerminal) {
Expand All @@ -53,14 +71,24 @@ export class BumpDecoupledLocalDependencies extends CommandLineAction {

this.#feedUrlParameter = this.defineStringParameter({
parameterLongName: '--feed-url',
description: 'The package feed URL to query for the latest published versions.',
description: 'The package feed URL to query for published versions not found in the input file.',
argumentName: 'FEED_URL'
});

this.#publishedVersionsPathParameter = this.defineStringParameter({
parameterLongName: '--published-versions-path',
description: 'The path to the published-versions.json file.',
argumentName: 'PATH'
});
}

protected override async onExecuteAsync(): Promise<void> {
const terminal: ITerminal = this.#terminal;
const feedUrl: string | undefined = this.#feedUrlParameter.value;
const publishedVersionsPath: string | undefined = this.#publishedVersionsPathParameter.value;
const publishedVersions: Record<string, string> | undefined = publishedVersionsPath
? await JsonFile.loadAsync(path.resolve(publishedVersionsPath))
: undefined;
const rushConfiguration: RushConfiguration = RushConfiguration.loadFromDefaultLocation({
startingFolder: process.cwd()
});
Expand Down Expand Up @@ -137,6 +165,7 @@ export class BumpDecoupledLocalDependencies extends CommandLineAction {
const version: string = await _getLatestPublishedVersionAsync(
terminal,
decoupledLocalDependencyName,
publishedVersions,
feedUrl
);
decoupledLocalDependencyVersionsByName.set(decoupledLocalDependencyName, version);
Expand Down Expand Up @@ -194,6 +223,7 @@ export class BumpDecoupledLocalDependencies extends CommandLineAction {
const latestRushVersion: string = await _getLatestPublishedVersionAsync(
terminal,
'@microsoft/rush',
publishedVersions,
feedUrl
);
const rushJson: IRushConfigurationJson = await JsonFile.loadAsync(rushJsonFile);
Expand Down