Repository navigation
220 lines (191 loc) · 7.29 KB
/
Copy pathpython-publish.yml
File metadata and controls
220 lines (191 loc) · 7.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
name: Release
on:
push:
tags:
- 'v2.[0-9]+.[0-9]+'
release:
types: [published]
permissions:
contents: read
concurrency:
group: release-${{ github.event.release.tag_name || github.ref_name }}
cancel-in-progress: false
jobs:
verify:
name: Verify release
if: github.event_name == 'push'
runs-on: ubuntu-latest
env:
RELEASE_TAG: ${{ github.ref_name }}
GOTOOLCHAIN: local
steps:
- name: Check out release tag
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
cache: false
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Verify Go module and release tag
shell: bash
run: |
set -euo pipefail
if [[ ! "$RELEASE_TAG" =~ ^v2\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]]; then
printf 'Invalid stable v2 tag: %s\n' "$RELEASE_TAG" >&2
exit 1
fi
if [[ "$(go list -m)" != gosuda.org/randflake/v2 ]]; then
printf 'Go module must be gosuda.org/randflake/v2\n' >&2
exit 1
fi
test "$(git rev-parse HEAD)" = "$(git rev-parse --verify "$GITHUB_REF^{commit}")"
- name: Verify coordinated package versions
shell: python
run: |
import json
import os
from pathlib import Path
import tomllib
version = os.environ["RELEASE_TAG"].removeprefix("v")
manifests = [Path("package.json")]
for package in ("sparx64", "randflake"):
directory = Path("src/randflake-ts") / package
manifests.extend((directory / "package.json", directory / "jsr.json"))
for manifest in manifests:
actual = json.loads(manifest.read_text())["version"]
if actual != version:
raise ValueError(f"{manifest}: version {actual!r} does not match {version!r}")
with open("pyproject.toml", "rb") as manifest:
actual = tomllib.load(manifest)["project"]["version"]
if actual != version:
raise ValueError(f"pyproject.toml: version {actual!r} does not match {version!r}")
- name: Test Go
run: go test -v ./...
- name: Test Go with race detector
run: go test -race ./...
- name: Vet Go
run: go vet ./...
- name: Build external Go consumer from tagged source
shell: bash
env:
GOPROXY: "off"
run: |
set -euo pipefail
scratch=$(mktemp -d)
trap 'rm -rf -- "$scratch"' EXIT
mkdir "$scratch/module" "$scratch/consumer"
git archive HEAD | tar -x -C "$scratch/module"
go -C "$scratch/consumer" mod init release.example/consumer
go -C "$scratch/consumer" mod edit \
"-require=gosuda.org/randflake/v2@$RELEASE_TAG" \
"-replace=gosuda.org/randflake/v2=$scratch/module"
go -C "$scratch/consumer" build gosuda.org/randflake/v2 gosuda.org/randflake/v2/legacy
npm:
name: Publish npm packages
if: github.event_name == 'push'
needs: verify
uses: ./.github/workflows/npm-publish.yml
secrets:
npm_token: ${{ secrets.npm_token }}
release-build:
name: Build Python package
needs: verify
if: ${{ !cancelled() && (needs.verify.result == 'success' || (github.event_name == 'release' && needs.verify.result == 'skipped')) }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Test Python
run: python -m unittest discover -s src/randflake -t src
- name: Build release distributions
shell: bash
run: |
set -euo pipefail
SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD)
export SOURCE_DATE_EPOCH
python -m pip install build
python -m build
- name: Upload distributions
uses: actions/upload-artifact@v4
with:
name: release-dists
path: dist/
if-no-files-found: error
overwrite: true
pypi-publish:
name: Publish Python package
needs: release-build
if: ${{ !cancelled() && needs.release-build.result == 'success' }}
runs-on: ubuntu-latest
permissions:
id-token: write
environment:
name: pypi
url: https://pypi.org/p/randflake
steps:
- name: Retrieve release distributions
uses: actions/download-artifact@v4
with:
name: release-dists
path: dist/
- name: Publish release distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/
skip-existing: true
jsr:
name: Publish JSR packages
if: github.event_name == 'push'
needs: npm
permissions:
contents: read
id-token: write
uses: ./.github/workflows/jsr-publish.yml
github-release:
name: Publish GitHub Release
if: github.event_name == 'push'
needs: [npm, pypi-publish, jsr]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Create or update GitHub Release
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_TAG: ${{ github.ref_name }}
run: |
set -euo pipefail
gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$RELEASE_TAG" --silent
notes=$(mktemp)
trap 'rm -f -- "$notes"' EXIT
version=${RELEASE_TAG#v}
cat > "$notes" <<EOF
This release publishes Go, Python, npm, and JSR packages together at $version, including the sparx64 packages.
## Install
- Go: \`go get gosuda.org/randflake/v2@$RELEASE_TAG\`
- Python: \`python -m pip install randflake==$version\`
- npm: \`npm install randflake@$version\`
- JSR: \`npx jsr add @safe/randflake@$version\`
## Go migration
Go 1.23 or newer is required. The module root \`gosuda.org/randflake/v2\` exposes \`Config\`, \`New\`, and \`Generator\` with whole Unix seconds and half-open leases \`[Start, EndExclusive)\`.
For the compatibility API, import \`randflake "gosuda.org/randflake/v2/legacy"\`. It retains \`NewGenerator\`, inclusive lease ends, and the legacy inspection signatures. Existing imports of \`gosuda.org/randflake\` must migrate to the v2 module path.
The encrypted 64-bit ID layout and string format are preserved; existing IDs remain readable with the same key. This is a library release, distributed through Go modules and the package registries, without platform binaries.
EOF
existing_release=$(gh api --paginate "repos/$GITHUB_REPOSITORY/releases?per_page=100" \
| jq -r --arg tag "$RELEASE_TAG" '.[] | select(.tag_name == $tag) | .id')
if [[ -n "$existing_release" ]]; then
gh release edit "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" \
--title "$RELEASE_TAG" --notes-file "$notes" --draft=false
else
gh release create "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" --verify-tag \
--title "$RELEASE_TAG" --notes-file "$notes"
fi