Skip to content

Commit d6ea449

Browse files
committed
ci: split publish to build and publish
1 parent d8a56a4 commit d6ea449

File tree

4 files changed

+101
-8
lines changed

4 files changed

+101
-8
lines changed

.ado/azure-pipelines.publish.yml

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,20 @@ extends:
4545
environmentsEs6: true
4646
environmentsNode: true
4747
stages:
48-
- stage: main
48+
- stage: Build
49+
displayName: Build & Pack
4950
jobs:
50-
- job: NPMPublish
51-
displayName: NPM Publish
51+
- job: BuildAndPack
52+
displayName: Build, Test & Pack
5253
pool:
5354
name: Azure-Pipelines-1ESPT-ExDShared
5455
image: ubuntu-latest
5556
os: linux
5657
templateContext:
5758
outputs:
5859
- output: pipelineArtifact
59-
targetPath: $(System.DefaultWorkingDirectory)
60-
artifactName: dist
60+
targetPath: $(System.DefaultWorkingDirectory)/_packed
61+
artifactName: packed-tarballs
6162
steps:
6263
- task: UseNode@1
6364
inputs:
@@ -70,25 +71,69 @@ extends:
7071
7172
- script: |
7273
yarn buildci
73-
displayName: 'yarn buildci [test]'
74+
displayName: 'yarn buildci [build + test + lint]'
75+
76+
- script: |
77+
yarn lage pack --verbose --grouped
78+
displayName: 'Pack all public packages'
79+
80+
- script: |
81+
echo "Packed tarballs:"
82+
ls -la $(System.DefaultWorkingDirectory)/_packed/
83+
displayName: 'List packed tarballs'
84+
85+
- stage: Publish
86+
displayName: Publish to NPM
87+
dependsOn: Build
88+
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'), not(${{ parameters.skipNpmPublish }}))
89+
jobs:
90+
- job: PublishPackages
91+
displayName: Publish NPM Packages
92+
pool:
93+
name: Azure-Pipelines-1ESPT-ExDShared
94+
image: ubuntu-latest
95+
os: linux
96+
steps:
97+
- task: UseNode@1
98+
inputs:
99+
version: '22.x'
100+
displayName: 'Use Node.js 22.x'
101+
102+
- task: DownloadPipelineArtifact@2
103+
inputs:
104+
artifactName: packed-tarballs
105+
targetPath: $(System.DefaultWorkingDirectory)/_packed
106+
displayName: 'Download packed tarballs'
107+
108+
- script: |
109+
echo "Downloaded tarballs:"
110+
ls -la $(System.DefaultWorkingDirectory)/_packed/
111+
displayName: 'List downloaded tarballs'
112+
113+
- script: |
114+
yarn --immutable
115+
displayName: 'yarn install --immutable'
74116
75117
- script: |
76118
yarn config set npmPublishAccess public
77119
yarn config set npmPublishRegistry "https://registry.npmjs.org"
78120
yarn config set npmAuthToken $(npmAuth)
79121
displayName: 'Configure yarn for npm publishing'
80-
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'), not(${{ parameters.skipNpmPublish }}))
81122
82123
- script: |
83124
# https://github.com/changesets/changesets/issues/432
84125
# We can't use `changeset publish` because it doesn't support workspaces, so we have to publish each package individually
85126
yarn lage publish --verbose --grouped --reporter azureDevops
86127
displayName: 'Publish NPM Packages'
87-
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'), not(${{ parameters.skipNpmPublish }}))
88128
89129
- script: |
90130
yarn config unset npmPublishAccess
91131
yarn config unset npmAuthToken
92132
yarn config unset npmPublishRegistry
93133
displayName: 'Cleanup yarn npm config'
94134
condition: always()
135+
136+
- script: |
137+
git clean -dfx
138+
displayName: 'Clean up working directory'
139+
condition: always()

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ typings/
7979
# Output of 'npm pack'
8080
*.tgz
8181

82+
# Pack staging directory
83+
_packed/
84+
8285
# Yarn Integrity file
8386
.yarn-integrity
8487

lage.config.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ const config = {
4646
inputs: [],
4747
outputs: [],
4848
},
49+
pack: {
50+
dependsOn: ['build-all', '^pack'],
51+
type: 'worker',
52+
options: {
53+
worker: 'scripts/src/worker/pack.mts',
54+
outputDir: '_packed',
55+
},
56+
cache: false,
57+
},
4958
publish: {
5059
dependsOn: ['^publish'],
5160
type: 'worker',

scripts/src/worker/pack.mts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type { WorkerRunnerFunction } from 'lage';
2+
3+
import { $, fs } from 'zx';
4+
import { join, resolve } from 'node:path';
5+
6+
/**
7+
* Lage worker that runs `yarn npm pack` for each public package,
8+
* collecting the resulting .tgz files into a flat staging directory.
9+
*
10+
* The output directory is passed via `target.options.outputDir` in lage.config.js.
11+
* The tgz filename is derived from the package name and version so it is
12+
* unique and easy to correlate back to the package.
13+
*/
14+
export const run: WorkerRunnerFunction = async ({ target }) => {
15+
const pkg = await fs.readJson(join(target.cwd, 'package.json'));
16+
17+
if (pkg.private) {
18+
return;
19+
}
20+
21+
const outputDir = target.options?.outputDir as string | undefined;
22+
if (!outputDir) {
23+
throw new Error('pack worker requires options.outputDir to be set in lage.config.js');
24+
}
25+
26+
// Resolve relative to cwd (lage runs from repo root, so this resolves correctly)
27+
const stagingDir = resolve(outputDir);
28+
await fs.mkdirp(stagingDir);
29+
30+
// Build a safe filename: @fluentui-react-native/button@1.0.0 -> fluentui-react-native-button-1.0.0.tgz
31+
const safeName = (pkg.name as string).replace(/@/g, '').replace(/\//g, '-');
32+
const tgzFilename = `${safeName}-${pkg.version}.tgz`;
33+
const outPath = join(stagingDir, tgzFilename);
34+
35+
await $({ cwd: target.cwd, verbose: true })`yarn pack --out ${outPath}`;
36+
};

0 commit comments

Comments
 (0)