Skip to content

Commit ee2e1e0

Browse files
author
adil.rakhaliyev
committed
Fix: turn publish workflow into a composite action
1 parent 7be6734 commit ee2e1e0

2 files changed

Lines changed: 163 additions & 214 deletions

File tree

.github/workflows/publish.yml

Lines changed: 0 additions & 214 deletions
This file was deleted.

actions/publish/action.yml

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
name: Publish
2+
description: Publish an npm package with version validation, audit, and provenance
3+
4+
inputs:
5+
pre-publish-script:
6+
description: 'Script that runs before publishing'
7+
required: false
8+
post-publish-script:
9+
description: 'Script that runs after publishing'
10+
required: false
11+
publish-command:
12+
description: 'Command used to publish the package'
13+
required: false
14+
default: 'npm publish'
15+
publish-tag:
16+
description: 'NPM dist-tag used when publishing'
17+
required: false
18+
default: 'latest'
19+
audit-level:
20+
description: 'The level of vulnerabilities to fail on (low, moderate, high, critical)'
21+
required: false
22+
default: 'low'
23+
omit-dev-dependencies:
24+
description: 'Whether to skip devDependencies in npm audit'
25+
required: false
26+
default: 'false'
27+
version:
28+
description: 'Version to publish (must start with v, e.g. v1.2.3)'
29+
required: true
30+
31+
runs:
32+
using: composite
33+
steps:
34+
- id: fetch_tags
35+
run: git fetch --force --tags
36+
shell: bash
37+
38+
- name: Get tag on current commit
39+
id: latest_tag
40+
run: echo "value=$(git tag --points-at HEAD | head -n 1)" >> $GITHUB_OUTPUT
41+
shell: bash
42+
43+
- name: Normalize input version
44+
id: input_version
45+
run: |
46+
RAW_VERSION="${{ inputs.version }}"
47+
NORMALIZED_VERSION="${RAW_VERSION#v}"
48+
echo "raw=$RAW_VERSION" >> "$GITHUB_OUTPUT"
49+
echo "value=$NORMALIZED_VERSION" >> "$GITHUB_OUTPUT"
50+
shell: bash
51+
52+
- name: Validate version input format
53+
id: validate_version_format
54+
if: ${{ !startsWith(inputs.version, 'v') }}
55+
run: |
56+
echo "Error: version input must start with 'v' (for example: v1.2.3). Received: ${{ inputs.version }}"
57+
echo "❌ Error: version input must start with 'v' (for example: v1.2.3). Received: ${{ inputs.version }}" >> "$GITHUB_STEP_SUMMARY"
58+
exit 1
59+
shell: bash
60+
61+
- name: Check if latest tag exists
62+
id: check_latest_tag_exists
63+
if: ${{ !steps.latest_tag.outputs.value }}
64+
run: |
65+
echo "Error: No tag found for the current commit."
66+
echo "❌ Error: No tag found for the current commit." >> "$GITHUB_STEP_SUMMARY"
67+
exit 1
68+
shell: bash
69+
70+
- name: Check latest tag matches version
71+
id: check_latest_tag_matches_version
72+
if: ${{ steps.latest_tag.outputs.value != inputs.version }}
73+
run: |
74+
echo "Error: Latest tag ${{ steps.latest_tag.outputs.value }} does not match the expected tag for version ${{ inputs.version }}"
75+
echo "❌ Error: Latest tag ${{ steps.latest_tag.outputs.value }} does not match the expected tag for version ${{ inputs.version }}" >> "$GITHUB_STEP_SUMMARY"
76+
exit 1
77+
shell: bash
78+
79+
- name: Get package.json version
80+
id: package_version
81+
run: |
82+
VERSION=$(node -p "require('./package.json').version")
83+
echo "value=$VERSION" >> "$GITHUB_OUTPUT"
84+
shell: bash
85+
86+
- name: Check package.json version
87+
id: check_package_version
88+
if: ${{ steps.package_version.outputs.value != steps.input_version.outputs.value }}
89+
run: |
90+
echo "Error: package.json version ${{ steps.package_version.outputs.value }} does not match normalized version ${{ steps.input_version.outputs.value }} (from input ${{ inputs.version }})"
91+
echo "❌ Error: package.json version ${{ steps.package_version.outputs.value }} does not match normalized version ${{ steps.input_version.outputs.value }} (from input ${{ inputs.version }})" >> "$GITHUB_STEP_SUMMARY"
92+
exit 1
93+
shell: bash
94+
95+
- id: setup_node
96+
uses: actions/setup-node@v6
97+
with:
98+
node-version: latest
99+
registry-url: 'https://registry.npmjs.org'
100+
101+
- name: Check for vulnerable dependencies
102+
id: npm_audit
103+
run: npm audit ${{ inputs.omit-dev-dependencies == 'true' && '--omit=dev' || '' }} --audit-level=${{ inputs.audit-level }}
104+
shell: bash
105+
106+
- name: Install dependencies
107+
id: npm_ci
108+
run: npm ci
109+
shell: bash
110+
111+
- name: Running pre-publish script
112+
id: pre_publish_script
113+
if: ${{ inputs.pre-publish-script }}
114+
run: ${{ inputs.pre-publish-script }}
115+
shell: bash
116+
117+
- name: Publish package
118+
id: publish_package
119+
run: ${{ inputs.publish-command }} --tag ${{ inputs.publish-tag }}
120+
shell: bash
121+
122+
- name: Running post-publish script
123+
id: post_publish_script
124+
if: ${{ inputs.post-publish-script }}
125+
run: ${{ inputs.post-publish-script }}
126+
shell: bash
127+
128+
- name: Publish summary
129+
if: ${{ always() }}
130+
run: |
131+
{
132+
echo "## Publish workflow summary"
133+
echo ""
134+
echo "- Job status: **${{ job.status }}**"
135+
echo "- Input version: \`${{ inputs.version }}\`"
136+
echo "- Normalized version: \`${{ steps.input_version.outputs.value }}\`"
137+
echo "- Publish tag: \`${{ inputs.publish-tag }}\`"
138+
echo "- Publish step outcome: \`${{ steps.publish_package.outcome }}\`"
139+
echo ""
140+
echo "### Failed checks"
141+
} >> "$GITHUB_STEP_SUMMARY"
142+
143+
FAILED=0
144+
145+
add_failure() {
146+
echo "- ❌ $1" >> "$GITHUB_STEP_SUMMARY"
147+
FAILED=1
148+
}
149+
150+
[ "${{ steps.validate_version_format.outcome }}" = "failure" ] && add_failure "Version input format validation failed (must start with 'v')."
151+
[ "${{ steps.check_latest_tag_exists.outcome }}" = "failure" ] && add_failure "No git tag found on the checked-out commit."
152+
[ "${{ steps.check_latest_tag_matches_version.outcome }}" = "failure" ] && add_failure "Current commit tag does not match provided version input."
153+
[ "${{ steps.check_package_version.outcome }}" = "failure" ] && add_failure "package.json version does not match normalized version input."
154+
[ "${{ steps.npm_audit.outcome }}" = "failure" ] && add_failure "npm audit failed for the configured audit level."
155+
[ "${{ steps.npm_ci.outcome }}" = "failure" ] && add_failure "npm ci failed."
156+
[ "${{ steps.pre_publish_script.outcome }}" = "failure" ] && add_failure "Pre-publish script failed."
157+
[ "${{ steps.publish_package.outcome }}" = "failure" ] && add_failure "Publish step failed."
158+
[ "${{ steps.post_publish_script.outcome }}" = "failure" ] && add_failure "Post-publish script failed."
159+
160+
if [ "$FAILED" -eq 1 ]; then
161+
echo "" >> "$GITHUB_STEP_SUMMARY"
162+
fi
163+
shell: bash

0 commit comments

Comments
 (0)