1515 type : string
1616 default : ' ["ubuntu-latest"]'
1717 required : false
18+ working-directory :
19+ description : " Working directory where the dependencies are installed."
20+ type : string
21+ required : false
22+ default : " ."
1823 build-artifact-id :
1924 description : |
2025 Build artifact ID from a previous CI job to download before publishing.
2328 type : string
2429 required : false
2530 default : " "
26- package-tarball :
27- description : |
28- Path to a pre-built package tarball to publish (e.g., `my-package-1.0.0.tgz`).
29- Use this when publishing a specific tarball file instead of running npm publish from source.
30- Supports glob patterns to match tarball files.
31- type : string
32- required : false
33- default : " "
34- access :
35- description : |
36- Package access level for npm publish.
37- - `public` — Publicly accessible package
38- - `restricted` — Scoped package with restricted access
39- Leave empty to use package.json default.
40- type : string
41- required : false
42- default : " "
43- docs :
44- description : |
45- Documentation generation parameters.
46- Set to empty string or `false` to disable documentation generation.
47- Set to `true` or a string to enable documentation generation with the default command `docs`.
48- Accepts a JSON object for advanced options:
49-
50- - `command`: Command to run for documentation generation (default: `docs`).
51- - `output`: Output directory for documentation (default: `docs`).
52- - `artifact`: Whether to upload documentation as an artifact (default: `false`).
53-
54- Example:
55- ```json
56- {
57- "command": "build:docs",
58- "output": "docs-dist",
59- "artifact": true
60- }
61- ```
62- type : string
63- required : false
64- default : " "
6531 registry :
6632 description : |
6733 Registry configuration for package publishing.
8551 type : string
8652 required : false
8753 default : " npm"
88- publish-command :
89- description : |
90- Command to run for publishing the package.
91- Defaults to `publish` which runs `npm publish` or equivalent for the detected package manager.
92- Can be customized for monorepo setups or specific publish requirements.
93-
94- Examples:
95- - `publish` — Default npm/pnpm/yarn publish
96- - `release` — Custom publish script in package.json
97- - `publish --access public` — Publish with specific npm flags
98- type : string
99- required : false
100- default : " publish"
10154 tag :
10255 description : |
10356 npm distribution tag for the published package.
11063 type : string
11164 required : false
11265 default : " latest"
113- dry-run :
114- description : |
115- Whether to perform a dry run (no actual publish).
116- Useful for testing the release workflow without publishing.
117- type : boolean
118- required : false
119- default : false
120- provenance :
121- description : |
122- Whether to generate provenance attestation for the published package.
123- Requires npm 9.5.0+ and appropriate permissions.
124- See https://docs.npmjs.com/generating-provenance-statements.
125- type : boolean
126- required : false
127- default : true
128- working-directory :
129- description : " Working directory where the package is located."
130- type : string
131- required : false
132- default : " ."
133- secrets :
134- registry-token :
135- description : |
136- Authentication token for the registry.
137- For npm: Use an npm access token with publish permissions.
138- For GitHub Packages: Use `GITHUB_TOKEN` or a PAT with `packages:write` permission.
139- required : true
140- outputs :
141- version :
142- description : " The version of the published package."
143- value : ${{ jobs.release.outputs.version }}
144- package-name :
145- description : " The name of the published package."
146- value : ${{ jobs.release.outputs.package-name }}
147- docs-artifact-id :
148- description : " ID of the documentation artifact (if uploaded)."
149- value : ${{ jobs.release.outputs.docs-artifact-id }}
15066
15167permissions : {}
15268
@@ -210,47 +126,6 @@ jobs:
210126 core.setOutput('registry-url', registryUrl);
211127 core.setOutput('registry-scope', registryScope);
212128
213- - id : parse-docs
214- uses : actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
215- env :
216- DOCS_INPUT : ${{ inputs.docs }}
217- with :
218- script : |
219- const docsInput = process.env.DOCS_INPUT.trim();
220-
221- if (!docsInput || docsInput === 'false') {
222- core.info('Documentation generation disabled');
223- return;
224- }
225-
226- let command = 'docs';
227- let output = 'docs';
228- let artifact = false;
229-
230- if (docsInput === 'true') {
231- // Use defaults
232- } else if (docsInput.startsWith('{')) {
233- try {
234- const config = JSON.parse(docsInput);
235- command = config.command || 'docs';
236- output = config.output || 'docs';
237- artifact = config.artifact === true;
238- } catch (error) {
239- return core.setFailed(`Failed to parse docs input as JSON: ${error.message}`);
240- }
241- } else {
242- // Treat as custom command
243- command = docsInput;
244- }
245-
246- core.info(`Docs command: ${command}`);
247- core.info(`Docs output: ${output}`);
248- core.info(`Docs artifact: ${artifact}`);
249-
250- core.setOutput('command', command);
251- core.setOutput('output', output);
252- core.setOutput('artifact', artifact ? 'true' : '');
253-
254129 release :
255130 name : 🚀 Release
256131 runs-on : ${{ inputs.runs-on && fromJson(inputs.runs-on) || 'ubuntu-latest' }}
@@ -260,10 +135,6 @@ jobs:
260135 contents : read
261136 packages : write
262137 id-token : write # Required for provenance
263- outputs :
264- version : ${{ steps.package-info.outputs.version }}
265- package-name : ${{ steps.package-info.outputs.name }}
266- docs-artifact-id : ${{ steps.upload-docs.outputs.artifact-id }}
267138 steps :
268139 - uses : hoverkraft-tech/ci-github-common/actions/checkout@5ac504609f6ef35c5ac94bd8199063aa32104721 # 0.31.3
269140
@@ -282,8 +153,8 @@ jobs:
282153 if : inputs.build-artifact-id != ''
283154 uses : actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
284155 with :
285- artifact-ids : ${{ inputs.build-artifact-id }}
286- path : /
156+ name : ${{ inputs.build-artifact-id }}
157+ path : ${{ github.workspace }}
287158
288159 - id : package-info
289160 uses : actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
@@ -325,53 +196,6 @@ jobs:
325196 core.setOutput('name', name);
326197 core.setOutput('version', version);
327198
328- - name : Generate documentation
329- if : needs.prepare.outputs.docs-command != ''
330- uses : actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
331- env :
332- DOCS_COMMAND : ${{ needs.prepare.outputs.docs-command }}
333- RUN_SCRIPT_COMMAND : ${{ steps.setup-node.outputs.run-script-command }}
334- WORKING_DIRECTORY : ${{ inputs.working-directory }}
335- with :
336- script : |
337- const fs = require('node:fs');
338- const path = require('node:path');
339-
340- let workingDirectory = process.env.WORKING_DIRECTORY || '.';
341- if (!path.isAbsolute(workingDirectory)) {
342- workingDirectory = path.join(process.env.GITHUB_WORKSPACE, workingDirectory);
343- }
344-
345- if (!fs.existsSync(workingDirectory)) {
346- return core.setFailed(`Working directory does not exist: ${workingDirectory}`);
347- }
348-
349- const docsCommand = process.env.DOCS_COMMAND;
350- const runScriptCommand = process.env.RUN_SCRIPT_COMMAND;
351-
352- core.info(`Running documentation command: ${docsCommand}`);
353-
354- try {
355- const exitCode = await exec.exec(runScriptCommand, [docsCommand], {
356- cwd: workingDirectory,
357- ignoreReturnCode: true
358- });
359-
360- if (exitCode !== 0) {
361- return core.setFailed(`Documentation generation failed with exit code ${exitCode}`);
362- }
363- } catch (error) {
364- return core.setFailed(`Documentation generation failed: ${error.message}`);
365- }
366-
367- - id : upload-docs
368- if : needs.prepare.outputs.docs-artifact == 'true'
369- uses : actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
370- with :
371- name : documentation-${{ github.run_id }}
372- path : ${{ inputs.working-directory }}/${{ needs.prepare.outputs.docs-output }}
373- if-no-files-found : error
374-
375199 - name : Publish package
376200 uses : actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
377201 env :
@@ -389,7 +213,6 @@ jobs:
389213 script : |
390214 const fs = require('node:fs');
391215 const path = require('node:path');
392- const { glob } = require('glob');
393216
394217 let workingDirectory = process.env.WORKING_DIRECTORY || '.';
395218 if (!path.isAbsolute(workingDirectory)) {
@@ -409,25 +232,50 @@ jobs:
409232 const runScriptCommand = process.env.RUN_SCRIPT_COMMAND;
410233 const registryUrl = process.env.REGISTRY_URL;
411234
235+ // Simple glob matching function
236+ function matchGlob(pattern, filename) {
237+ const regexPattern = pattern
238+ .replace(/\./g, '\\.')
239+ .replace(/\*/g, '.*')
240+ .replace(/\?/g, '.');
241+ return new RegExp(`^${regexPattern}$`).test(filename);
242+ }
243+
412244 // Determine what to publish
413245 let publishTarget = null;
414246
415247 if (packageTarball) {
416248 // Publishing a specific tarball file
417- const tarballPattern = path.isAbsolute(packageTarball)
418- ? packageTarball
419- : path.join(workingDirectory, packageTarball);
420-
421- const matches = await glob(tarballPattern, { nodir: true });
422-
249+ let searchDir = workingDirectory;
250+ let filePattern = packageTarball;
251+
252+ if (path.isAbsolute(packageTarball)) {
253+ searchDir = path.dirname(packageTarball);
254+ filePattern = path.basename(packageTarball);
255+ } else if (packageTarball.includes('/')) {
256+ searchDir = path.join(workingDirectory, path.dirname(packageTarball));
257+ filePattern = path.basename(packageTarball);
258+ }
259+
260+ if (!fs.existsSync(searchDir)) {
261+ return core.setFailed(`Search directory does not exist: ${searchDir}`);
262+ }
263+
264+ // Find matching files
265+ const allFiles = fs.readdirSync(searchDir);
266+ const matches = allFiles
267+ .filter(file => matchGlob(filePattern, file))
268+ .map(file => path.join(searchDir, file))
269+ .filter(file => fs.statSync(file).isFile());
270+
423271 if (matches.length === 0) {
424- return core.setFailed(`No tarball found matching pattern: ${packageTarball}`);
272+ return core.setFailed(`No tarball found matching pattern: ${packageTarball} in ${searchDir} `);
425273 }
426-
274+
427275 if (matches.length > 1) {
428276 core.warning(`Multiple tarballs found: ${matches.join(', ')}. Using first match.`);
429277 }
430-
278+
431279 publishTarget = matches[0];
432280 core.info(`Publishing tarball: ${publishTarget}`);
433281 }
0 commit comments