-
Notifications
You must be signed in to change notification settings - Fork 0
179 lines (164 loc) · 5.99 KB
/
Copy pathrelease-publish.yml
File metadata and controls
179 lines (164 loc) · 5.99 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
# Publish an openprotein-python release.
#
# Triggered by merging a pull request labeled `release`. The version is read from
# .release-please-manifest.json; on merge it creates + pushes the vX.Y.Z tag (so
# hatch-vcs can derive the version), builds the wheel + sdist + conda package,
# publishes to PyPI via OIDC trusted publishing (no token), uploads the conda
# package to anaconda.org, and cuts the GitHub release with all three assets.
#
# Every build/release job checks out the merge commit with fetch-depth: 0 so
# hatch-vcs and the changelog compare-link have full tag history.
#
# Required repo config:
# - PyPI trusted publisher registered for OpenProteinAI/openprotein-python +
# workflow release-publish.yml (no secret needed for PyPI).
# - secret ANACONDA_TOKEN — anaconda.org API token for `anaconda upload`.
# - var ANACONDA_OWNER — anaconda.org user/org (channel) to upload to.
name: release-publish
on:
pull_request:
types: [closed]
workflow_dispatch: {} # manual re-run (reads the version from the manifest on main)
jobs:
build:
# A merged PR labeled `release`, or a manual dispatch.
if: >-
github.event_name == 'workflow_dispatch' ||
(github.event.pull_request.merged == true &&
contains(github.event.pull_request.labels.*.name, 'release'))
runs-on: ubuntu-latest
permissions:
contents: write # push the release tag
defaults:
run:
shell: bash -el {0}
outputs:
tag: ${{ steps.resolve.outputs.tag }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.merge_commit_sha || github.sha }}
fetch-depth: 0
- name: Resolve version + create tag
id: resolve
run: |
TAG="v$(jq -r '."."' .release-please-manifest.json)"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
if git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then
echo "Tag ${TAG} already exists; skipping tag creation (re-run)."
else
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag -a "${TAG}" -m "${TAG}"
git push origin "${TAG}"
fi
# Build from the tag so hatch-vcs produces the exact release version.
# (On a manual re-run, main may have advanced past the tag, which would
# otherwise yield a rejected dev/local version like 0.16.2.dev1+g….)
git checkout -q "refs/tags/${TAG}"
- name: Set up conda (conda-build + anaconda-client)
uses: conda-incubator/setup-miniconda@v3
with:
miniforge-version: latest
channels: conda-forge
python-version: "3.11"
- name: Install build tooling
run: |
conda install -y -c conda-forge conda-build anaconda-client
pip install hatch
- name: Build wheel + sdist
run: hatch build
- name: Stage python dists
run: |
mkdir -p pypi-dist
cp dist/*.whl dist/*.tar.gz pypi-dist/
- name: Build conda package
run: |
hatch build -t conda
mkdir -p conda-dist
cp dist/conda/noarch/*.conda conda-dist/
- uses: actions/upload-artifact@v4
with:
name: pypi-dist
path: pypi-dist/
- uses: actions/upload-artifact@v4
with:
name: conda-dist
path: conda-dist/
pypi:
needs: build
runs-on: ubuntu-latest
permissions:
id-token: write # OIDC trusted publishing
steps:
- uses: actions/download-artifact@v4
with:
name: pypi-dist
path: dist/
- name: Publish to PyPI (OIDC)
uses: pypa/gh-action-pypi-publish@release/v1
with:
skip-existing: true # idempotent on re-run
conda:
needs: build
runs-on: ubuntu-latest
defaults:
run:
shell: bash -el {0}
steps:
- uses: actions/download-artifact@v4
with:
name: conda-dist
path: conda-dist/
- uses: conda-incubator/setup-miniconda@v3
with:
miniforge-version: latest
channels: conda-forge
- name: Upload to anaconda.org
env:
ANACONDA_TOKEN: ${{ secrets.ANACONDA_TOKEN }}
ANACONDA_OWNER: ${{ vars.ANACONDA_OWNER }}
run: |
conda install -y -c conda-forge anaconda-client
anaconda -t "$ANACONDA_TOKEN" upload --user "$ANACONDA_OWNER" --force conda-dist/*.conda
github-release:
needs: [build, pypi, conda]
runs-on: ubuntu-latest
permissions:
contents: write
env:
TAG: ${{ needs.build.outputs.tag }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/download-artifact@v4
with:
name: pypi-dist
path: dist/
- uses: actions/download-artifact@v4
with:
name: conda-dist
path: dist/
- name: Create GitHub release
env:
GH_TOKEN: ${{ github.token }}
run: |
# Pull this version's bullet points from the (sanitized) CHANGELOG.
section=$(awk -v hdr="## ${TAG#v} " 'index($0,hdr)==1{c=1;next} c&&/^## /{exit} c{print}' CHANGELOG.md | sed '/./,$!d')
prev=$(git describe --tags --abbrev=0 "${TAG}^" 2>/dev/null || echo "")
notes="${section:-Release ${TAG}}"
if [ -n "$prev" ]; then
notes="${notes}
**Full Changelog**: https://github.com/${GITHUB_REPOSITORY}/compare/${prev}...${TAG}"
fi
if gh release view "${TAG}" >/dev/null 2>&1; then
echo "Release ${TAG} exists; updating notes + assets (re-run)."
gh release edit "${TAG}" --notes "${notes}"
gh release upload "${TAG}" dist/*.whl dist/*.tar.gz dist/*.conda --clobber
else
gh release create "${TAG}" \
--title "${TAG}" \
--notes "${notes}" \
dist/*.whl dist/*.tar.gz dist/*.conda
fi