Skip to content

Commit e902570

Browse files
Merge pull request #352 from webpack/ci/publish-ref-on-demand
ci: let the release workflow publish a given ref on demand
2 parents e0036c9 + 6289926 commit e902570

1 file changed

Lines changed: 77 additions & 1 deletion

File tree

‎.github/workflows/release.yml‎

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ on:
44
push:
55
branches:
66
- main
7+
# Publishes a version that a commit carries but npm never received, e.g.
8+
# after a failed release run; the checked-out commit is published as is
9+
workflow_dispatch:
10+
inputs:
11+
ref:
12+
description: "Commit, tag or branch whose package.json version to publish"
13+
required: true
14+
dist-tag:
15+
description: "npm dist-tag; anything but `latest` for a version older than the current one"
16+
required: true
17+
default: latest
718

819
concurrency: ${{ github.workflow }}-${{ github.ref }}
920

@@ -14,7 +25,7 @@ permissions:
1425

1526
jobs:
1627
release:
17-
if: github.repository == 'webpack/watchpack'
28+
if: github.repository == 'webpack/watchpack' && github.event_name == 'push'
1829
name: Release
1930
runs-on: ubuntu-latest
2031
outputs:
@@ -38,3 +49,68 @@ jobs:
3849
publish-script: npm run release
3950
commit-message: "chore(release): new release"
4051
pr-title: "chore(release): new release"
52+
53+
publish-ref:
54+
if: github.repository == 'webpack/watchpack' && github.event_name == 'workflow_dispatch'
55+
name: Publish ${{ inputs.ref }}
56+
runs-on: ubuntu-latest
57+
steps:
58+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
59+
with:
60+
ref: ${{ inputs.ref }}
61+
fetch-depth: 0
62+
persist-credentials: false
63+
64+
- name: Use Node.js
65+
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
66+
with:
67+
node-version: lts/*
68+
registry-url: https://registry.npmjs.org
69+
70+
- name: Check the commit, version and tag
71+
id: version
72+
env:
73+
DIST_TAG: ${{ inputs.dist-tag }}
74+
run: |
75+
if ! git merge-base --is-ancestor HEAD origin/main; then
76+
echo "::error::$(git rev-parse HEAD) is not on main; only reviewed commits are published"
77+
exit 1
78+
fi
79+
version="$(node -p 'require("./package.json").version')"
80+
if npm view "watchpack@$version" version > /dev/null 2>&1; then
81+
echo "::error::watchpack@$version is already on npm"
82+
exit 1
83+
fi
84+
if [ "$DIST_TAG" = latest ]; then
85+
latest="$(npm view watchpack dist-tags.latest)"
86+
if ! node -e '
87+
const [version, latest] = process.argv.slice(1);
88+
const parse = (v) => v.split("-")[0].split(".").map(Number);
89+
const [a, b] = [parse(version), parse(latest)];
90+
const diff = a[0] - b[0] || a[1] - b[1] || a[2] - b[2];
91+
const newer = !version.includes("-") && (diff > 0 || (diff === 0 && latest.includes("-")));
92+
process.exit(newer ? 0 : 1);
93+
' "$version" "$latest"; then
94+
echo "::error::$version is a prerelease or not newer than latest ($latest); pick another dist-tag"
95+
exit 1
96+
fi
97+
fi
98+
tagged="$(git ls-remote --tags origin "refs/tags/v$version^{}" "refs/tags/v$version" | sort -k2 | tail -n1 | cut -f1)"
99+
if [ -n "$tagged" ] && [ "$tagged" != "$(git rev-parse HEAD)" ]; then
100+
echo "::error::tag v$version already points to $tagged"
101+
exit 1
102+
fi
103+
echo "version=$version" >> "$GITHUB_OUTPUT"
104+
105+
- name: Publish to npm
106+
env:
107+
DIST_TAG: ${{ inputs.dist-tag }}
108+
run: npm publish --access public --tag "$DIST_TAG"
109+
110+
- name: Create the tag and GitHub release
111+
env:
112+
GH_TOKEN: ${{ github.token }}
113+
VERSION: ${{ steps.version.outputs.version }}
114+
run: |
115+
awk -v v="$VERSION" '$0 == "## " v { found = 1; next } found && /^## / { exit } found' CHANGELOG.md > notes.md
116+
gh release create "v$VERSION" --target "$(git rev-parse HEAD)" --title "v$VERSION" --notes-file notes.md

0 commit comments

Comments
 (0)