Skip to content

Commit 175b6d8

Browse files
committed
ci: update publish workflow to trigger on successful test completion
1 parent 2ce3de9 commit 175b6d8

2 files changed

Lines changed: 146 additions & 11 deletions

File tree

.github/workflows/publish.yml

Lines changed: 145 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,172 @@
11
name: Publish to PyPI
22

33
on:
4-
push:
5-
tags:
6-
- "v*"
4+
workflow_run:
5+
workflows: ["Tests"]
6+
types: [completed]
7+
branches: []
78

89
permissions:
910
contents: write
1011

1112
jobs:
12-
get-version:
13+
setup:
14+
name: Pre-flight Check
1315
runs-on: ubuntu-latest
16+
if: >
17+
github.event.workflow_run.conclusion == 'success' &&
18+
github.event.workflow_run.event == 'push' &&
19+
startsWith(github.event.workflow_run.head_branch, 'v')
1420
outputs:
21+
is_release: ${{ steps.check.outputs.is_release }}
1522
version: ${{ steps.version.outputs.version }}
23+
tag_name: ${{ steps.check.outputs.tag_name }}
24+
commit_sha: ${{ steps.check.outputs.commit_sha }}
1625
steps:
17-
- name: Extract version
26+
- name: Determine trigger context
27+
id: context
28+
run: |
29+
if [ "${{ github.event_name }}" == "push" ]; then
30+
echo "trigger_type=direct_tag" >> $GITHUB_OUTPUT
31+
echo "tag_name=${{ github.ref_name }}" >> $GITHUB_OUTPUT
32+
echo "commit_sha=${{ github.sha }}" >> $GITHUB_OUTPUT
33+
else
34+
echo "trigger_type=workflow_run" >> $GITHUB_OUTPUT
35+
echo "tag_name=${{ github.event.workflow_run.head_branch }}" >> $GITHUB_OUTPUT
36+
echo "commit_sha=${{ github.event.workflow_run.head_sha }}" >> $GITHUB_OUTPUT
37+
fi
38+
39+
- uses: actions/checkout@v4
40+
with:
41+
ref: ${{ steps.context.outputs.commit_sha }}
42+
fetch-depth: 0
43+
fetch-tags: true
44+
45+
- name: Verify Tag
46+
id: check
47+
run: |
48+
TRIGGER_NAME="${{ steps.context.outputs.tag_name }}"
49+
TRIGGER_SHA="${{ steps.context.outputs.commit_sha }}"
50+
TRIGGER_TYPE="${{ steps.context.outputs.trigger_type }}"
51+
52+
echo "🔎 Analyzing trigger: $TRIGGER_NAME ($TRIGGER_SHA)"
53+
echo "Trigger type: $TRIGGER_TYPE"
54+
55+
# Version tag regex
56+
# Matches: v1.2.3, v1.2.3a1, v1.2.3b2, v1.2.3rc1, v1.2.3.post1, v1.2.3.dev0
57+
if [[ ! "$TRIGGER_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(a|b|rc|\.post|\.dev)?[0-9]*$ ]]; then
58+
echo "::notice::Skipping: '$TRIGGER_NAME' is not a valid release tag."
59+
echo "Expected format: vX.Y.Z or vX.Y.Z{a,b,rc,.post,.dev}N"
60+
echo "is_release=false" >> $GITHUB_OUTPUT
61+
exit 0
62+
fi
63+
64+
if ! git fetch origin "refs/tags/$TRIGGER_NAME:refs/tags/$TRIGGER_NAME" 2>&1; then
65+
echo "::warning::Failed to fetch tag $TRIGGER_NAME - may not exist yet"
66+
fi
67+
68+
# Check if this is actually a tag
69+
TAG_SHA=$(git rev-list -n 1 "refs/tags/$TRIGGER_NAME" 2>/dev/null || echo "NOT_FOUND")
70+
71+
if [ "$TAG_SHA" == "NOT_FOUND" ]; then
72+
echo "::notice::Skipping: Tag 'refs/tags/$TRIGGER_NAME' does not exist."
73+
echo "is_release=false" >> $GITHUB_OUTPUT
74+
exit 0
75+
fi
76+
77+
if [ "$TAG_SHA" != "$TRIGGER_SHA" ]; then
78+
echo "::warning::SHA Mismatch - not a tag release!"
79+
echo " - Event SHA: $TRIGGER_SHA (The code that was tested)"
80+
echo " - Tag SHA: $TAG_SHA (The actual tag)"
81+
echo " This is likely a branch named '$TRIGGER_NAME', not the tag."
82+
echo "is_release=false" >> $GITHUB_OUTPUT
83+
exit 0
84+
fi
85+
86+
# Check if this version already exists on PyPI
87+
VERSION="${TRIGGER_NAME#v}"
88+
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "https://pypi.org/pypi/canirun/$VERSION/json")
89+
90+
if [ "$HTTP_CODE" == "200" ]; then
91+
echo "::warning::Version $VERSION already exists on PyPI. Skipping republish."
92+
echo "is_release=false" >> $GITHUB_OUTPUT
93+
exit 0
94+
elif [ "$HTTP_CODE" != "404" ]; then
95+
echo "::error::Unable to verify PyPI status (HTTP $HTTP_CODE). Aborting for safety."
96+
echo "Check https://pypi.org/pypi/canirun/$VERSION/json manually."
97+
echo "is_release=false" >> $GITHUB_OUTPUT
98+
exit 1
99+
fi
100+
101+
echo "✅ Verified: Valid release tag with matching commit."
102+
echo "is_release=true" >> $GITHUB_OUTPUT
103+
echo "tag_name=$TRIGGER_NAME" >> $GITHUB_OUTPUT
104+
echo "commit_sha=$TRIGGER_SHA" >> $GITHUB_OUTPUT
105+
106+
- name: Extract Version
18107
id: version
108+
if: steps.check.outputs.is_release == 'true'
19109
run: |
20-
VERSION=${GITHUB_REF_NAME#v}
21-
echo "version=$VERSION" >> $GITHUB_OUTPUT
110+
VERSION="${{ steps.check.outputs.tag_name }}"
111+
echo "version=${VERSION#v}" >> $GITHUB_OUTPUT
22112
23-
build-and-release:
113+
- name: Verify package version matches tag
114+
if: steps.check.outputs.is_release == 'true'
115+
run: |
116+
TAG_VERSION="${{ steps.version.outputs.version }}"
117+
VERSION_MISMATCH=0
118+
119+
# Check pyproject.toml
120+
if [ -f "pyproject.toml" ]; then
121+
PKG_VERSION=$(grep -E '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/' | tr -d ' ')
122+
if [ -n "$PKG_VERSION" ]; then
123+
if [ "$PKG_VERSION" != "$TAG_VERSION" ]; then
124+
echo "::error::pyproject.toml version mismatch!"
125+
echo " Tag version: $TAG_VERSION"
126+
echo " pyproject.toml version: $PKG_VERSION"
127+
VERSION_MISMATCH=1
128+
else
129+
echo "✅ pyproject.toml version matches: $TAG_VERSION"
130+
fi
131+
fi
132+
fi
133+
134+
# Check canirun/__init__.py
135+
if [ -f "canirun/__init__.py" ]; then
136+
INIT_VERSION=$(grep -E '^__version__ = ' canirun/__init__.py | sed 's/__version__ = "\(.*\)"/\1/' | tr -d ' ' || echo "")
137+
if [ -n "$INIT_VERSION" ]; then
138+
if [ "$INIT_VERSION" != "$TAG_VERSION" ]; then
139+
echo "::error::__init__.py version mismatch!"
140+
echo " Tag version: $TAG_VERSION"
141+
echo " __init__.py __version__: $INIT_VERSION"
142+
VERSION_MISMATCH=1
143+
else
144+
echo "✅ __init__.py __version__ matches: $TAG_VERSION"
145+
fi
146+
fi
147+
fi
148+
149+
if [ $VERSION_MISMATCH -eq 1 ]; then
150+
echo "is_release=false" >> $GITHUB_OUTPUT
151+
exit 1
152+
fi
153+
154+
publish:
24155
name: Build and Release
25-
needs: get-version
156+
needs: setup
157+
if: needs.setup.outputs.is_release == 'true'
26158
runs-on: ubuntu-latest
27159
permissions:
28160
contents: write
29161
id-token: write
30162
environment:
31163
name: pypi
32-
url: https://pypi.org/project/canirun/${{ needs.get-version.outputs.version }}/
164+
url: https://pypi.org/project/canirun/${{ needs.setup.outputs.version }}/
33165

34166
steps:
35167
- uses: actions/checkout@v4
168+
with:
169+
ref: ${{ needs.setup.outputs.commit_sha }}
36170

37171
- name: Set up Python
38172
uses: actions/setup-python@v5
@@ -49,8 +183,8 @@ jobs:
49183

50184
- name: Create GitHub Release
51185
uses: softprops/action-gh-release@v2
52-
if: startsWith(github.ref, 'refs/tags/')
53186
with:
187+
tag_name: ${{ needs.setup.outputs.tag_name }}
54188
files: dist/*
55189
generate_release_notes: true
56190

.github/workflows/tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ name: Tests
33
on:
44
push:
55
branches: [ "master" ]
6+
tags: [ "v*" ]
67
pull_request:
78
branches: [ "master" ]
89

0 commit comments

Comments
 (0)