Title: ci(pythonpublish): add workflow_dispatch trigger for republishing tags by bearomorphism · Pull Request #1981 · commitizen-tools/commitizen · GitHub
Open Graph Title: ci(pythonpublish): add workflow_dispatch trigger for republishing tags by bearomorphism · Pull Request #1981 · commitizen-tools/commitizen
X Title: ci(pythonpublish): add workflow_dispatch trigger for republishing tags by bearomorphism · Pull Request #1981 · commitizen-tools/commitizen
Description: Description Closes #1790. Why The publish run for v4.11.1 failed at the time of the original tag push and the release is absent from PyPI — confirmed by the triage comment on #1790: "Confirmed via https://pypi.org/pypi/commitizen/json — 4.11.1 is not in the release history." GitHub disallows re-running workflow runs older than 30 days via the UI or API, so the original job cannot be retried. The practical recovery options are: recreate the tag (which re-fires the GitHub release workflow and risks breaking downstream automation that watches tag events), use a separate ad-hoc workflow, or add a workflow_dispatch trigger to the existing publish workflow so a maintainer can invoke it manually for any tag. The third option is the least invasive — it touches only the trigger block and one checkout parameter — and it becomes a permanent escape hatch for any future failed publish run without requiring tag recreation or out-of-band tooling. What changed File Change .github/workflows/pythonpublish.yml Add workflow_dispatch trigger with a required ref string input; update the actions/checkout step to use ${{ inputs.ref || github.ref_name }} How it works workflow_dispatch block (.github/workflows/pythonpublish.yml:4–7 on master, extended by the patch): a single required string input named ref is declared, so the Actions UI presents a labelled text field when "Run workflow" is clicked. Marking it required: true prevents an accidental no-argument dispatch that would fall through to an ambiguous default. Checkout fallback expression: the checkout step's ref parameter changes from the hardcoded ${{ github.ref_name }} at .github/workflows/pythonpublish.yml:20 (master) to ${{ inputs.ref || github.ref_name }}. On push events the inputs context is empty, so the expression short-circuits to github.ref_name — the tag that triggered the push — producing identical behaviour to the previous value. On workflow_dispatch events inputs.ref is the maintainer-supplied tag string and that value is used directly. Repository guard unchanged (.github/workflows/pythonpublish.yml:11, master): the if: ${{ github.repository == 'commitizen-tools/commitizen' }} condition on the deploy job applies to both trigger types, so forks cannot accidentally publish by dispatching this workflow. OIDC trusted-publisher path unchanged: the permissions: id-token: write block at .github/workflows/pythonpublish.yml:13–15 (master) is preserved as-is. The PyPI trusted-publisher configuration accepts OIDC tokens issued for workflow_dispatch events on the same terms as for push events — no PyPI-side reconfiguration is needed. Backward compatibility The automatic push: tags: ["v*"] trigger at .github/workflows/pythonpublish.yml:4–7 (master) is unchanged; all future automatic releases behave identically. fetch-depth: 0 is preserved so the full tag history remains available to uv build and to commitizen's own version introspection. No Python source files are touched; uv run poe all reports no new lint or type errors. Checklist I have read the contributing guidelines Was generative AI tooling used to co-author this PR? Yes (please specify the tool below) Generated-by: Claude following the guidelines Code Changes Add test cases to all the changes you introduce Run uv run poe all locally to ensure this change passes linter check and tests Manually test the changes (see "Steps to Test" below) Update the documentation for the changes Expected Behavior Scenario Outcome Normal tag push (e.g., v4.16.0) Workflow triggers automatically; inputs.ref is empty so github.ref_name is used — identical to pre-patch behaviour Manual dispatch with ref = v4.11.1 Workflow checks out the v4.11.1 tag, runs uv build, and publishes to PyPI via the existing OIDC trusted-publisher flow Manual dispatch from a fork deploy job is skipped; github.repository != 'commitizen-tools/commitizen' Manual dispatch with no value in the ref field UI blocks submission because required: true is set Steps to Test This Pull Request git fetch fork fix/1790-publish-workflow-dispatch git checkout fork/fix/1790-publish-workflow-dispatch # 1. Targeted regression test — validate YAML syntax. python -c "import yaml; yaml.safe_load(open('.github/workflows/pythonpublish.yml')); print('OK: YAML parses cleanly')" # 2. Reproduce-the-bug-then-verify-the-fix sequence. # Before this PR: republishing v4.11.1 requires recreating the tag. # After merge: a maintainer can dispatch the workflow manually. # # Structural verification (can be run pre-merge): python - <<'EOF' import yaml wf = yaml.safe_load(open(".github/workflows/pythonpublish.yml")) triggers = wf["on"] assert "push" in triggers, "push trigger missing" assert "workflow_dispatch" in triggers, "workflow_dispatch trigger missing" inp = triggers["workflow_dispatch"]["inputs"]["ref"] assert inp["required"] is True, "ref input must be required" assert inp["type"] == "string", "ref input must be type string" steps = wf["jobs"]["deploy"]["steps"] checkout = next(s for s in steps if "actions/checkout" in str(s.get("uses", ""))) assert "inputs.ref" in checkout["with"]["ref"], "checkout ref must use inputs.ref fallback" guard = wf["jobs"]["deploy"]["if"] assert "commitizen-tools/commitizen" in guard, "repo guard must still be present" print("OK: workflow structure is correct") EOF # Post-merge functional test (requires maintainer access): # 1. Go to https://github.com/commitizen-tools/commitizen/actions/workflows/pythonpublish.yml # 2. Click "Run workflow" → enter "v4.11.1" in the ref field → "Run workflow" # 3. Verify the run succeeds and https://pypi.org/project/commitizen/4.11.1/ becomes available Additional Context This fix was surfaced during the #1964 issue audit. The triage comment on #1790 confirmed that v4.11.1 remains absent from PyPI and that the original workflow run is too old to be re-run through the GitHub UI. The workflow_dispatch trigger is intentionally minimal — a single ref input, no pre-flight tag validation — to keep the diff small and the blast radius low. A potential follow-up hardening would add a git describe --exact-match --tags "$ref" pre-flight check to guard against accidentally dispatching with a branch name (PyPI would reject a duplicate version upload, but the build step would still run unnecessarily); that is left as a separate issue to keep this PR focused on unblocking the v4.11.1 republish.
Open Graph Description: Description Closes #1790. Why The publish run for v4.11.1 failed at the time of the original tag push and the release is absent from PyPI — confirmed by the triage comment on #1790: "Confirmed...
X Description: Description Closes #1790. Why The publish run for v4.11.1 failed at the time of the original tag push and the release is absent from PyPI — confirmed by the triage comment on #1790: "Confi...
Opengraph URL: https://github.com/commitizen-tools/commitizen/pull/1981
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:dc368d1d-64e4-5ed7-fa59-7f389a73a465 |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | 9ED2:FB1CA:84A58F:B6ECF3:6A4DB5B0 |
| html-safe-nonce | ebdfee0261cedaa0017306770f02ef5ffa1371e6c579277e701e72c8f9ad55a2 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5RUQyOkZCMUNBOjg0QTU4RjpCNkVDRjM6NkE0REI1QjAiLCJ2aXNpdG9yX2lkIjoiMzAwMTU5MTI4MzAzNjU2Njk2MCIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 39da58a7909e6e80796b484e2dcea73d55ca2780838ff592d4ed7dd4523dad1a |
| hovercard-subject-tag | pull_request:3654799234 |
| github-keyboard-shortcuts | repository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/commitizen-tools/commitizen/pull/1981/files |
| twitter:image | https://avatars.githubusercontent.com/u/26526132?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/26526132?s=400&v=4 |
| og:image:alt | Description Closes #1790. Why The publish run for v4.11.1 failed at the time of the original tag push and the release is absent from PyPI — confirmed by the triage comment on #1790: "Confirmed... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 06b8a6144231bf3a234f1c2e9993861e07ce98a905912b114aa386c2d7e84b33 |
| turbo-cache-control | no-preview |
| diff-view | unified |
| go-import | github.com/commitizen-tools/commitizen git https://github.com/commitizen-tools/commitizen.git |
| octolytics-dimension-user_id | 62252524 |
| octolytics-dimension-user_login | commitizen-tools |
| octolytics-dimension-repository_id | 106127589 |
| octolytics-dimension-repository_nwo | commitizen-tools/commitizen |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 106127589 |
| octolytics-dimension-repository_network_root_nwo | commitizen-tools/commitizen |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | true |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 32f7b614aca06e6bbd89842b1370df1328264f68 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width