Skip to content

fix: Package-and-Upload workflow attaches binaries to UI-created releases - #459

Open
jacalata wants to merge 1 commit into
developmentfrom
jac/fix-package-workflow-upload
Open

fix: Package-and-Upload workflow attaches binaries to UI-created releases#459
jacalata wants to merge 1 commit into
developmentfrom
jac/fix-package-workflow-upload

Conversation

@jacalata

Copy link
Copy Markdown
Contributor

Motivation

Investigating why the v2.0.21 release page shipped with no executables attached, we found two bugs in the Package-and-Upload workflow. v2.0.19 had the same failure mode for the same reason.

Behavior change

Before: the "Upload binaries to release" step was gated on

if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')

Releases created via the GitHub UI create a tag but don't fire the push:tags: event that this workflow depends on. So the workflow only ran manually via workflow_dispatch afterward, built the binaries as workflow artifacts, and skipped the upload-to-release step because the if: guard requires push. The binaries were sitting in the artifact store for 90 days, never on the release.

Separately, both macOS build jobs used name: tabcmd-macos on actions/upload-artifact, so the two same-named artifacts collided in the artifact store and gh run download clobbered one with the other.

After:

  • New release_tag workflow_dispatch input. Set it when dispatching from a branch to attach binaries to a UI-created release. Falls back to github.ref_name when the workflow runs on a tag ref (push or dispatch).
  • Mac artifact collision fixed: matrix.UPLOAD_FILE_NAME (unique per platform) is now the artifact name instead of tabcmd-${{ matrix.TARGET }}.
  • Upload logic split into a new upload_to_release job that depends on buildexe, gated on environment: release. Anyone with dispatch access can trigger a build, but only an approved reviewer can attach binaries to a public release. Mirrors the existing pypi environment gate on this repo (PR security: add environment gate to production PyPI publish job #439).

Prerequisite before merging

The release environment already exists in this repo's Settings -> Environments with required-reviewer protection. Confirm it's still configured before merging; if it isn't, the upload_to_release job will run unguarded.

Test plan

  • Live-verified today via gh release upload v2.0.21 ... (with the artifacts downloaded from the last workflow_dispatch run) that the platform binaries were the right ones and could be attached to v2.0.21. The v2.0.21 release page now shows all four assets, retroactively fixed.
  • End-to-end verification after merge: for v2.0.22 or a test tag, either push a tag or create a UI release and dispatch the workflow with the release_tag input; confirm the approval gate fires and the four binaries end up on the release page.
  • Code review from code-reviewer agent — no blocking findings; added inline comments for the upload-artifact@v7 / download-artifact@v8 major mismatch (both are current best; upload@v8 doesn't exist yet) and the needs: buildexe all-matrix-legs-must-succeed semantics.

🤖 Generated with Claude Code

…ases

Two bugs found while investigating why v2.0.21 shipped without
executables attached:

1. The "Upload binaries to release" step was gated on
   `github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')`.
   Releases created via the GitHub UI create a tag but do not fire the
   push:tags: event that this workflow depends on, so v2.0.21 (and v2.0.19)
   ended up as releases with no assets. The only successful run for
   v2.0.21 was a workflow_dispatch afterward that built the binaries as
   artifacts but skipped the upload-to-release step.
2. Both macOS build jobs used `name: tabcmd-macos` on
   `actions/upload-artifact`, so the two same-named artifacts collided in
   the artifact store and downloads clobbered each other.

Fixes:

- New `release_tag` workflow_dispatch input. Set it when dispatching from
  a branch to attach binaries to a UI-created release. Falls back to
  `github.ref_name` when the workflow runs on a tag ref (push or dispatch).
- Fix mac artifact collision: use `matrix.UPLOAD_FILE_NAME` (unique per
  platform) as the artifact name instead of `tabcmd-${{ matrix.TARGET }}`.
- Split the upload into a separate `upload_to_release` job that depends on
  `buildexe`, gated on `environment: release`. The `release` environment
  needs to be created in the repo's Settings -> Environments with
  required-reviewer protection (mirroring the existing `pypi` environment).
  Anyone with dispatch access can trigger a build, but only an approved
  reviewer can attach binaries to a public release.
- Upload gate: `if: startsWith(github.ref, 'refs/tags/') || inputs.release_tag != ''`
  so both the push:tags path and the workflow_dispatch path work.

Live-verified by using `gh release upload` today to fix v2.0.21
retroactively with the artifacts from the last workflow_dispatch run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Coverage

Coverage Report
FileStmtsMissCoverMissing
tabcmd
   __main__.py121212 0%
   _version.py111111 0%
   tabcmd.py151515 0%
   version.py955 44%
tabcmd/commands
   commands.py101010 0%
   constants.py771818 77%
   server.py1351818 87%
tabcmd/commands/auth
   session.py3945050 87%
tabcmd/commands/datasources_and_workbooks
   datasources_and_workbooks_command.py1571818 89%
   datasources_workbooks_views_url_parser.py14255 96%
   delete_command.py601616 73%
   export_command.py1202525 79%
   get_url_command.py1274747 63%
   publish_command.py1232828 77%
   runschedule_command.py2177 67%
tabcmd/commands/extracts
   create_extracts_command.py4288 81%
   decrypt_extracts_command.py2722 93%
   delete_extracts_command.py3766 84%
   encrypt_extracts_command.py2722 93%
   extracts.py2022 90%
   reencrypt_extracts_command.py2722 93%
   refresh_extracts_command.py481010 79%
tabcmd/commands/group
   create_group_command.py2955 83%
   delete_group_command.py2722 93%
tabcmd/commands/project
   create_project_command.py4688 83%
   delete_project_command.py3544 89%
   publish_samples_command.py3044 87%
tabcmd/commands/site
   create_site_command.py3455 85%
   delete_site_command.py2722 93%
   edit_site_command.py3822 95%
   list_command.py771212 84%
   list_sites_command.py2922 93%
tabcmd/commands/user
   add_users_command.py2955 83%
   create_site_users.py581111 81%
   create_users_command.py5999 85%
   delete_site_users_command.py4355 88%
   user_data.py2223131 86%
tabcmd/execution
   _version.py222 0%
   global_options.py12588 94%
   localize.py661111 83%
   logger_config.py6066 90%
   tabcmd_controller.py4277 83%
TOTAL287345884% 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant