Skip to content

Commit 34ffd6a

Browse files
yarn workspaces foreach to publish
1 parent c23ad55 commit 34ffd6a

File tree

3 files changed

+233
-169
lines changed

3 files changed

+233
-169
lines changed

.ado/azure-pipelines.publish.yml

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ parameters:
1414
displayName: Skip Npm Publish
1515
type: boolean
1616
default: false
17-
- name: skipGitPush
18-
displayName: Skip Git Push
19-
type: boolean
20-
default: false
2117
- name: skipNugetPublish
2218
displayName: Skip Nuget Publish
2319
type: boolean
@@ -70,12 +66,6 @@ extends:
7066
steps:
7167
- template: .ado/templates/setup-repo.yml@self
7268

73-
- script: |
74-
git config user.name "UI-Fabric-RN-Bot"
75-
git config user.email "uifrnbot@microsoft.com"
76-
git remote set-url origin https://$(githubUser):$(githubPAT)@github.com/microsoft/fluentui-react-native.git
77-
displayName: Git Authentication
78-
7969
- script: |
8070
yarn
8171
displayName: 'yarn install'
@@ -85,11 +75,24 @@ extends:
8575
displayName: 'yarn buildci [test]'
8676
8777
- script: |
88-
yarn changeset:publish
89-
displayName: 'Publish NPM Packages with Changesets'
78+
yarn config set npmPublishRegistry "https://registry.npmjs.org"
79+
yarn config set npmAuthToken $(npmAuth)
80+
displayName: 'Configure yarn for npm publishing'
9081
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'), not(${{ parameters.skipNpmPublish }}))
91-
env:
92-
NPM_TOKEN: $(npmAuth)
82+
83+
- script: |
84+
# https://github.com/changesets/changesets/issues/432
85+
# We can't use `changeset publish` because it doesn't support workspaces, so we have to publish each package individually
86+
yarn workspaces foreach --all --topological --no-private \
87+
exec zx $(Build.SourcesDirectory)/.github/scripts/publish-package-if-needed.mts
88+
displayName: 'Publish NPM Packages'
89+
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'), not(${{ parameters.skipNpmPublish }}))
90+
91+
- script: |
92+
yarn config unset npmAuthToken
93+
yarn config unset npmPublishRegistry
94+
displayName: 'Cleanup yarn npm config'
95+
condition: always()
9396
9497
- template: .ado/templates/win32-nuget-publish.yml@self
9598
parameters:
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env zx
2+
import 'zx/globals';
3+
4+
// Type declaration for process (zx doesn't include Node.js types)
5+
declare const process: {
6+
env: Record<string, string | undefined>;
7+
cwd: () => string;
8+
argv: string[];
9+
exit: (code: number) => never;
10+
};
11+
12+
/**
13+
* Publish a single package to npm if needed
14+
*
15+
* This script:
16+
* - Operates on the current workspace directory
17+
* - Checks npm registry before publishing
18+
* - Skips private packages automatically
19+
*
20+
* Usage:
21+
* # In a workspace directory:
22+
* npx zx publish-package-if-needed.mts # Publish for real
23+
* npx zx publish-package-if-needed.mts --dry-run # Simulate publishing
24+
*
25+
* # For all workspaces in topological order:
26+
* yarn workspaces foreach --all --topological --no-private \
27+
* exec npx zx .github/scripts/publish-package-if-needed.mts
28+
*/
29+
30+
// Parse command line arguments
31+
const isDryRun = process.argv.includes('--dry-run');
32+
33+
// Read package.json from current directory
34+
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
35+
const { name, version, private: isPrivate } = packageJson;
36+
37+
// Skip private packages
38+
if (isPrivate) {
39+
echo(`⊘ Skipping private package: ${name}`);
40+
process.exit(0);
41+
}
42+
43+
// Check if package@version already exists on npm
44+
const result = await $`npm view ${name}@${version} version 2>&1`.nothrow().quiet();
45+
const shouldPublish = result.exitCode !== 0 || result.stdout.trim() !== version;
46+
47+
if (!shouldPublish) {
48+
echo(`✓ Already published: ${name}@${version}`);
49+
process.exit(0);
50+
}
51+
52+
// Publish the package
53+
const startMsg = isDryRun ? 'Simulating publish' : 'Publishing';
54+
const endMsg = isDryRun ? 'Dry-run successful for' : 'Successfully published';
55+
56+
echo(`→ ${startMsg}: ${name}@${version}`);
57+
58+
const publishCmd = isDryRun
59+
? $`yarn npm publish --access public --dry-run`
60+
: $`yarn npm publish --access public`;
61+
62+
await publishCmd;
63+
echo(`✓ ${endMsg}: ${name}@${version}`);

0 commit comments

Comments
 (0)