Skip to content

Commit f39fa37

Browse files
committed
fix(ci): add workflow_run trigger and tag verification to publish workflow
1 parent 0553824 commit f39fa37

File tree

4 files changed

+68
-15
lines changed

4 files changed

+68
-15
lines changed

.github/workflows/publish.yml

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ on:
55
push:
66
tags:
77
- "v*" # Triggers on tags like v0.1.0, v1.2.3, etc.
8+
workflow_run:
9+
workflows: ["Release on Github"]
10+
types:
11+
- completed
12+
branches:
13+
- main
814
workflow_dispatch:
915
inputs:
1016
testpypi_only:
@@ -16,6 +22,10 @@ on:
1622
jobs:
1723
publish:
1824
runs-on: ubuntu-latest
25+
if: |
26+
github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success' ||
27+
github.event_name == 'push' ||
28+
github.event_name == 'workflow_dispatch'
1929
environment: pypi
2030
permissions:
2131
id-token: write
@@ -25,6 +35,44 @@ jobs:
2535
uses: actions/checkout@v5
2636
with:
2737
fetch-depth: 0
38+
ref: ${{ github.event.workflow_run.head_branch || github.ref }}
39+
token: ${{ secrets.GITHUB_TOKEN }}
40+
41+
- name: Check if new tag exists
42+
id: check_tag
43+
run: |
44+
# Fetch all tags
45+
git fetch --tags
46+
# Get the latest tag matching v* pattern
47+
LATEST_TAG=$(git tag -l "v*" --sort=-version:refname | head -n 1)
48+
if [ -z "$LATEST_TAG" ]; then
49+
echo "No tag matching v* pattern found"
50+
echo "tag_exists=false" >> $GITHUB_OUTPUT
51+
exit 0
52+
fi
53+
54+
echo "Found latest tag: $LATEST_TAG"
55+
56+
# For workflow_run events, verify tag is associated with this workflow run
57+
if [ "${{ github.event_name }}" = "workflow_run" ]; then
58+
WORKFLOW_COMMIT="${{ github.event.workflow_run.head_sha }}"
59+
TAG_COMMIT=$(git rev-list -n 1 "$LATEST_TAG")
60+
61+
# Check if tag commit is reachable from workflow commit (same or newer)
62+
# This handles cases where semantic-release creates a new commit or tags existing commit
63+
if git merge-base --is-ancestor "$WORKFLOW_COMMIT" "$TAG_COMMIT" 2>/dev/null || [ "$TAG_COMMIT" = "$WORKFLOW_COMMIT" ]; then
64+
echo "Tag $LATEST_TAG is associated with this workflow run"
65+
echo "tag_exists=true" >> $GITHUB_OUTPUT
66+
echo "tag=$LATEST_TAG" >> $GITHUB_OUTPUT
67+
else
68+
echo "Tag $LATEST_TAG is not associated with this workflow run (no new release created)"
69+
echo "tag_exists=false" >> $GITHUB_OUTPUT
70+
fi
71+
else
72+
# For push (on tag) or workflow_dispatch, assume tag exists
73+
echo "tag_exists=true" >> $GITHUB_OUTPUT
74+
echo "tag=$LATEST_TAG" >> $GITHUB_OUTPUT
75+
fi
2876
2977
- name: Set up Python
3078
uses: actions/setup-python@v6
@@ -40,15 +88,23 @@ jobs:
4088
run: poetry install --no-interaction --no-root
4189

4290
- name: Build package
91+
if: |
92+
github.event_name == 'push' ||
93+
github.event_name == 'workflow_dispatch' ||
94+
steps.check_tag.outputs.tag_exists == 'true'
4395
run: poetry build
4496

4597
- name: Publish to TestPyPI
46-
if: github.event.inputs.testpypi_only == 'true'
98+
if: |
99+
(github.event_name == 'push' || github.event_name == 'workflow_dispatch' || steps.check_tag.outputs.tag_exists == 'true') &&
100+
github.event.inputs.testpypi_only == 'true'
47101
uses: pypa/gh-action-pypi-publish@release/v1
48102
with:
49103
repository-url: https://test.pypi.org/legacy/
50104

51105
- name: Publish to PyPI
52-
if: github.event.inputs.testpypi_only != 'true'
106+
if: |
107+
(github.event_name == 'push' || github.event_name == 'workflow_dispatch' || steps.check_tag.outputs.tag_exists == 'true') &&
108+
github.event.inputs.testpypi_only != 'true'
53109
uses: pypa/gh-action-pypi-publish@release/v1
54110

CHANGELOG.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,3 @@
1313
## v0.0.1 (2025-11-27)
1414

1515
- Initial Release
16-
17-
## v1.0.0 (2025-11-27)
18-
19-
- Initial Release

RELEASES.md

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

tests/00_tooling/test_pytest__runtime_mode_swap.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,14 @@
2525
import pytest
2626
from apathetic_logging import makeSafeTrace
2727

28-
import apathetic_utils as app_package
2928
import apathetic_utils.system as amod_utils_system
3029
from tests.utils import PROGRAM_PACKAGE, PROGRAM_SCRIPT, PROJ_ROOT
3130

3231

32+
# --- convenience -----------------------------------------------------------
33+
34+
_system = amod_utils_system.ApatheticUtils_Internal_System
35+
3336
# ---------------------------------------------------------------------------
3437
# Helpers
3538
# ---------------------------------------------------------------------------
@@ -43,13 +46,13 @@
4346
def list_important_modules() -> list[str]:
4447
"""Return all importable submodules under the package, if available."""
4548
important: list[str] = []
46-
if not hasattr(app_package, "__path__"):
49+
if not hasattr(amod_utils_system, "__path__"):
4750
safeTrace("pkgutil.walk_packages skipped — standalone runtime (no __path__)")
48-
important.append(app_package.__name__)
51+
important.append(amod_utils_system.__name__)
4952
else:
5053
for _, name, _ in pkgutil.walk_packages(
51-
app_package.__path__,
52-
app_package.__name__ + ".",
54+
amod_utils_system.__path__,
55+
amod_utils_system.__name__ + ".",
5356
):
5457
important.append(name)
5558

@@ -112,7 +115,7 @@ def test_pytest_runtime_cache_integrity() -> None:
112115
# the installed package if it was imported before runtime_swap ran)
113116
if mode == "singlefile" and "apathetic_utils.system" in sys.modules:
114117
# Use the module from sys.modules, which should be from the standalone script
115-
amod_utils_system_actual = sys.modules["apathetic_utils.system"]
118+
amod_utils_system_actual = sys.modules[f"{PROGRAM_PACKAGE}.system"]
116119
# Check __file__ directly - for stitched modules, should point to
117120
# dist/apathetic_utils.py
118121
utils_file_path = getattr(amod_utils_system_actual, "__file__", None)
@@ -132,7 +135,7 @@ def test_pytest_runtime_cache_integrity() -> None:
132135
if os.getenv("TRACE"):
133136
dump_snapshot()
134137
# Access via main module to get the function from the namespace class
135-
runtime_mode = app_package.detect_runtime_mode("apathetic_utils")
138+
runtime_mode = _system.detect_runtime_mode(PROGRAM_PACKAGE)
136139

137140
if mode == "singlefile":
138141
# --- verify singlefile ---

0 commit comments

Comments
 (0)