ci: let results reach a protected branch, and never lose a long run - #1065
Conversation
Two problems surfaced on the release pull request (#1061), whose head is develop: The results push was rejected (GH006, protected branch update failed). Every check had passed; only the commit failed. actions/checkout persists the credentials the push later uses, so the token belongs there: use CI_PUSH_TOKEN when it is set and fall back to GITHUB_TOKEN, which keeps every ordinary topic-branch head working and leaves forks unaffected. That failed push then skipped everything after it, because steps default to an implicit success(). On #1061 the MEMOTE artifact and the build-gate verdict were both skipped, so a plumbing failure hid which gate had actually run. The same shape would silently discard a multi-hour gene-essentiality or full-MEMOTE run, since their publish steps also sit after the commit. Guard the publish and verdict steps with !cancelled() instead: they now run whether or not the push succeeded, but still not on cancellation.
Model quality report
Each check name links to its explanation in the testResults README. Model checksDuplicate keys (model unloadable) and no growth block the merge; every other row is a non-blocking report.
MACAW and mass/charge balance
Model file and metabolic tasks
MEMOTETotal score: 63.2% (core subset) 0
Per-test scores
Full suite not run for this commit; comment The score above is the fast core subset. Comment Gene essentiality (Hart 2015)Not run automatically (it takes hours). Comment ❌ = a count rose vs the target branch (regression) · Full workflow run · this comment is edited as results come in |
Why
Both problems showed up on #1061, the release PR, whose head is
develop.1. The results push is rejected on a protected branch. Every check on #1061 passed. Only
Auto-commit resultsfailed:developrequires one approving review and has no bypass allowances, soGITHUB_TOKENcannot push to it. (github-actions[bot]cannot be added to a classic protection bypass list; only installed GitHub Apps appear there.)2. That failure then skipped everything after it. Steps default to an implicit
success(), so on #1061 bothUpload full MEMOTE resultandFail if a build gate failedwere skipped. The gate verdict never ran, meaning a plumbing failure masks which gate actually went red. The same shape would throw away a multi-hour/run gene-essentialityor/run memote, because their publish steps also sit after the commit.Changes
Token.
actions/checkoutpersists the credentials the later push uses, so that is where the token belongs, not on the auto-commit step. All three workflows now use:The fallback means nothing breaks before the secret exists, on forks where secrets are not exposed, or for ordinary topic-branch heads, which
GITHUB_TOKENcan already push to.Guards. The publish and verdict steps are now
if: ${{ !cancelled() }}instead of the implicitsuccess(), so they run whether or not the push succeeded, but still not when a run is cancelled:model-qc.ymlPost final comment,Upload full MEMOTE result,Fail if a build gate failedgene-essentiality.ymlPost commentmemote-full.ymlUpload full MEMOTE result,Update the Model QC commentRequired before this helps
CI_PUSH_TOKENmust exist as a repository secret, holding a PAT from an account with admin rights (enforce_adminsis false ondevelop, so an admin's credentials can push directly). Until then the fallback keeps current behaviour, and the release PR's push keeps failing.Note the trade-off of a PAT: it is a long-lived credential tied to a person, results commits will be attributed to that account rather than the bot, and it needs rotating. A dedicated GitHub App with
contents: writeadded to the bypass list is the scoped alternative if this becomes permanent.