diff --git a/.github/workflows/gene-essentiality.yml b/.github/workflows/gene-essentiality.yml index be78f01e..8a00f8b7 100644 --- a/.github/workflows/gene-essentiality.yml +++ b/.github/workflows/gene-essentiality.yml @@ -24,8 +24,12 @@ jobs: PYTHONUNBUFFERED: "1" steps: + # CI_PUSH_TOKEN lets the results push reach a protected branch (e.g. a run + # dispatched against develop); GITHUB_TOKEN is the fallback. See model-qc.yml. - name: Checkout uses: actions/checkout@v7 + with: + token: ${{ secrets.CI_PUSH_TOKEN || secrets.GITHUB_TOKEN }} - name: Set up Python 3 uses: actions/setup-python@v6 @@ -110,8 +114,10 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} PR_NUMBER: ${{ github.event.number }} + # !cancelled() rather than the implicit success(): this run takes hours, so its + # result must still be posted even if the results push above failed. - name: Post comment - if: inputs.pr != '' + if: ${{ !cancelled() && inputs.pr != '' }} uses: actions/github-script@v9 env: TEST_RESULTS: ${{ steps.essentiality.outputs.results }} diff --git a/.github/workflows/memote-full.yml b/.github/workflows/memote-full.yml index 80dc565d..8adaaf4f 100644 --- a/.github/workflows/memote-full.yml +++ b/.github/workflows/memote-full.yml @@ -25,8 +25,12 @@ jobs: timeout-minutes: 350 steps: + # CI_PUSH_TOKEN lets the results push reach a protected branch (e.g. a run + # dispatched against develop); GITHUB_TOKEN is the fallback. See model-qc.yml. - name: Checkout uses: actions/checkout@v7 + with: + token: ${{ secrets.CI_PUSH_TOKEN || secrets.GITHUB_TOKEN }} - name: Set up Python 3 uses: actions/setup-python@v6 @@ -91,7 +95,10 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # !cancelled() rather than the implicit success(): the full suite runs for hours, + # so the artifact and the comment must survive a failed results push above. - name: Upload full MEMOTE result + if: ${{ !cancelled() }} uses: actions/upload-artifact@v7 with: name: memote-result @@ -99,6 +106,7 @@ jobs: if-no-files-found: ignore - name: Update the Model QC comment + if: ${{ !cancelled() }} uses: ./.github/actions/post-qc-comment with: running-groups: "" diff --git a/.github/workflows/model-qc.yml b/.github/workflows/model-qc.yml index 08b92ea6..6ce3c4ab 100644 --- a/.github/workflows/model-qc.yml +++ b/.github/workflows/model-qc.yml @@ -35,8 +35,15 @@ jobs: RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} steps: + # actions/checkout persists these credentials for the results push below. The + # default GITHUB_TOKEN cannot push to a protected branch, which the release + # pull request needs (its head is develop), so use CI_PUSH_TOKEN when it is + # set and fall back to GITHUB_TOKEN otherwise (forks, or before the secret + # exists) - the fallback still works for every ordinary topic-branch head. - name: Checkout uses: actions/checkout@v7 + with: + token: ${{ secrets.CI_PUSH_TOKEN || secrets.GITHUB_TOKEN }} - name: Configure run: | @@ -206,9 +213,12 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Now that the results (including model_qc_summary.md) are committed, post the - # comment from the committed summary. + # comment from the committed summary. The steps from here on are guarded with + # !cancelled() rather than the implicit success(): if the results push fails + # (e.g. a protected head branch), the comment, the artifact and the gate verdict + # must still happen instead of being skipped, so a long run is never lost. - name: Post final comment - if: always() + if: ${{ !cancelled() }} uses: ./.github/actions/post-qc-comment with: mode: post @@ -217,6 +227,7 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Upload full MEMOTE result + if: ${{ !cancelled() }} uses: actions/upload-artifact@v7 with: name: memote-result @@ -226,7 +237,10 @@ jobs: # Fail the build if a gate failed, but only after the detail is committed and # the comment updated, so the failure is visible in both. Gates: structural QC # (duplicate keys / no growth), YAML round-trip, YAML lint, metabolic tasks. + # Runs even when an earlier step failed, so a plumbing failure (a rejected + # results push, say) can never mask which gate actually went red. - name: Fail if a build gate failed + if: ${{ !cancelled() }} run: | fail=0 [ "${{ steps.qc.outcome }}" = "failure" ] && fail=1 diff --git a/data/testResults/README.md b/data/testResults/README.md index 96b77f18..c1e46a26 100644 --- a/data/testResults/README.md +++ b/data/testResults/README.md @@ -21,11 +21,11 @@ own files. The pull request in each row is the one whose run last wrote those fi | Result file(s) | Produced by | Last updated by | | --- | --- | --- | -| `qc_duplicate_keys.csv`, `qc_empty_reactions.csv`, `qc_annotation_consistency.csv`, `qc_deprecation_completeness.csv`, `qc_metabolite_completeness.csv`, `qc_reaction_sanity.csv`, `qc_duplicate_reactions.csv`, `qc_unused_entities.csv`, `qc_growth_blockers.csv` | `qcModelChecks.py` | **PR #1062** (model QC checks) | -| `qc_annotation_issues.csv` | `annotationTest.py` | **PR #1062** (model QC checks) | -| `qc_status.tsv` (round-trip, YAML lint, metabolic tasks, growth) | `testYamlConversion.py`, `testMetabolicTasks.py`, `action-yamllint`, `qcModelChecks.py` (via `qcStatus.py`) | **PR #1062** (model QC checks) | -| `macaw_results.csv`, `balance_results.csv`, `qc_structure_consistency.csv` | `macawTests.py`, `balanceTest.py`, `structureConsistencyTest.py` | **PR #1062** (MACAW and balance) | -| `memote_score.md` | `memoteSnapshot.py` (fast subset every PR; full suite via `/run memote`) | **PR #1062** (MEMOTE) | +| `qc_duplicate_keys.csv`, `qc_empty_reactions.csv`, `qc_annotation_consistency.csv`, `qc_deprecation_completeness.csv`, `qc_metabolite_completeness.csv`, `qc_reaction_sanity.csv`, `qc_duplicate_reactions.csv`, `qc_unused_entities.csv`, `qc_growth_blockers.csv` | `qcModelChecks.py` | **PR #1065** (model QC checks) | +| `qc_annotation_issues.csv` | `annotationTest.py` | **PR #1065** (model QC checks) | +| `qc_status.tsv` (round-trip, YAML lint, metabolic tasks, growth) | `testYamlConversion.py`, `testMetabolicTasks.py`, `action-yamllint`, `qcModelChecks.py` (via `qcStatus.py`) | **PR #1065** (model QC checks) | +| `macaw_results.csv`, `balance_results.csv`, `qc_structure_consistency.csv` | `macawTests.py`, `balanceTest.py`, `structureConsistencyTest.py` | **PR #1065** (MACAW and balance) | +| `memote_score.md` | `memoteSnapshot.py` (fast subset every PR; full suite via `/run memote`) | **PR #1065** (MEMOTE) | | `gene-essential.csv`, `gene-essential_summary.md` | `geneEssentiality.py` via `/run gene-essentiality` | **PR #1027** (gene essentiality) | ## 2. What each check means diff --git a/data/testResults/model_qc_summary.md b/data/testResults/model_qc_summary.md index 393dffaf..2d807722 100644 --- a/data/testResults/model_qc_summary.md +++ b/data/testResults/model_qc_summary.md @@ -2,58 +2,58 @@ :warning: **6 pre-existing finding(s), no regressions vs `develop`.** Non-blocking. -_Each check name links to its explanation in the [testResults README](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md)._ +_Each check name links to its explanation in the [testResults README](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md)._ ### Model checks _Duplicate keys (model unloadable) and no growth block the merge; every other row is a non-blocking report._ | Check | Result | Δ vs `develop` | | | --- | ---: | ---: | :---: | -| [Duplicate `!!omap` keys](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#duplicate-omap-keys) | 0 | 0 | :white_check_mark: | -| [Growth (biomass producible)](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#growth-biomass-producible) | 125 | new | :white_check_mark: | -| [Reactions with no metabolites](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#reactions-with-no-metabolites) | 0 | 0 | :white_check_mark: | -| [Model / annotation-table inconsistencies](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#model--annotation-table-inconsistencies) | 0 | 0 | :white_check_mark: | -| [Removed reactions or metabolites not deprecated](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#removed-reactions-or-metabolites-not-deprecated) | 0 | new | :white_check_mark: | -| [Metabolites missing formula](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#metabolites-missing-formula) | 0 | 0 | :white_check_mark: | -| [Metabolites missing charge](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#metabolites-missing-charge) | 0 | 0 | :white_check_mark: | -| [Reaction bound / GPR issues](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#reaction-bound--gpr-issues) | 0 | 0 | :white_check_mark: | -| [Exact-duplicate reaction groups](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#exact-duplicate-reaction-groups) | 0 | 0 | :white_check_mark: | -| [Unused metabolites](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#unused-metabolites) | 0 | 0 | :white_check_mark: | -| [Unused genes](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#unused-genes) | 0 | 0 | :white_check_mark: | -| [Malformed cross-references](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#malformed-cross-references) | 0 | 0 | :white_check_mark: | -| [Cross-refs inconsistent across compartments](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#cross-refs-inconsistent-across-compartments) | [3](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/qc_annotation_issues.csv) | 0 | :warning: | +| [Duplicate `!!omap` keys](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#duplicate-omap-keys) | 0 | 0 | :white_check_mark: | +| [Growth (biomass producible)](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#growth-biomass-producible) | 125 | 0 | :white_check_mark: | +| [Reactions with no metabolites](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#reactions-with-no-metabolites) | 0 | 0 | :white_check_mark: | +| [Model / annotation-table inconsistencies](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#model--annotation-table-inconsistencies) | 0 | 0 | :white_check_mark: | +| [Removed reactions or metabolites not deprecated](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#removed-reactions-or-metabolites-not-deprecated) | 0 | 0 | :white_check_mark: | +| [Metabolites missing formula](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#metabolites-missing-formula) | 0 | 0 | :white_check_mark: | +| [Metabolites missing charge](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#metabolites-missing-charge) | 0 | 0 | :white_check_mark: | +| [Reaction bound / GPR issues](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#reaction-bound--gpr-issues) | 0 | 0 | :white_check_mark: | +| [Exact-duplicate reaction groups](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#exact-duplicate-reaction-groups) | 0 | 0 | :white_check_mark: | +| [Unused metabolites](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#unused-metabolites) | 0 | 0 | :white_check_mark: | +| [Unused genes](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#unused-genes) | 0 | 0 | :white_check_mark: | +| [Malformed cross-references](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#malformed-cross-references) | 0 | 0 | :white_check_mark: | +| [Cross-refs inconsistent across compartments](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#cross-refs-inconsistent-across-compartments) | [3](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/qc_annotation_issues.csv) | 0 | :warning: | ### MACAW and mass/charge balance | Check | Result | Δ vs `develop` | | | --- | ---: | ---: | :---: | -| [Reactions flagged by MACAW dead-end test](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#reactions-flagged-by-macaw-dead-end-test) | [2510](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/macaw_results.csv) | 0 | :warning: | -| [Reactions flagged as MACAW duplicates](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#reactions-flagged-as-macaw-duplicates) | [377](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/macaw_results.csv) | 0 | :warning: | -| [Mass-imbalanced reactions](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#mass-imbalanced-reactions) | [87](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/balance_results.csv) | 0 | :warning: | -| [Charge-imbalanced reactions](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#charge-imbalanced-reactions) | [234](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/balance_results.csv) | 0 | :warning: | -| [Structure vs formula/charge inconsistencies](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#structure-vs-formulacharge-inconsistencies) | [397](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/qc_structure_consistency.csv) | 0 | :warning: | +| [Reactions flagged by MACAW dead-end test](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#reactions-flagged-by-macaw-dead-end-test) | [2510](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/macaw_results.csv) | 0 | :warning: | +| [Reactions flagged as MACAW duplicates](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#reactions-flagged-as-macaw-duplicates) | [377](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/macaw_results.csv) | 0 | :warning: | +| [Mass-imbalanced reactions](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#mass-imbalanced-reactions) | [87](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/balance_results.csv) | 0 | :warning: | +| [Charge-imbalanced reactions](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#charge-imbalanced-reactions) | [234](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/balance_results.csv) | 0 | :warning: | +| [Structure vs formula/charge inconsistencies](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#structure-vs-formulacharge-inconsistencies) | [397](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/qc_structure_consistency.csv) | 0 | :warning: | ### Model file and metabolic tasks | Check | Result | | | --- | ---: | :---: | -| [YAML round-trip (cobrapy)](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#yaml-round-trip-cobrapy) | pass | :white_check_mark: | -| [YAML round-trip (RAVEN)](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#yaml-round-trip-raven) | pass | :white_check_mark: | -| [YAML lint](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#yaml-lint) | pass | :white_check_mark: | -| [Essential metabolic tasks](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#essential-metabolic-tasks) | 57 passed | :white_check_mark: | -| [Verification metabolic tasks](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#verification-metabolic-tasks) | 21 passed | :white_check_mark: | +| [YAML round-trip (cobrapy)](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#yaml-round-trip-cobrapy) | pass | :white_check_mark: | +| [YAML round-trip (RAVEN)](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#yaml-round-trip-raven) | pass | :white_check_mark: | +| [YAML lint](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#yaml-lint) | pass | :white_check_mark: | +| [Essential metabolic tasks](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#essential-metabolic-tasks) | 57 passed | :white_check_mark: | +| [Verification metabolic tasks](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#verification-metabolic-tasks) | 21 passed | :white_check_mark: | -### [MEMOTE](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#memote) +### [MEMOTE](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#memote) -**Total score: 63.2%** (core subset)   +43.0 :white_check_mark: +**Total score: 63.2%** (core subset)   0 | Section | Score | Δ vs base | | --- | ---: | ---: | | consistency | 42.4% | 0 | -| annotation_met | 73.0% | +48.0 :white_check_mark: | -| annotation_rxn | 72.7% | +47.7 :white_check_mark: | -| annotation_gene | 46.7% | +46.7 :white_check_mark: | -| annotation_sbo | 81.7% | +81.7 :white_check_mark: | +| annotation_met | 73.0% | 0 | +| annotation_rxn | 72.7% | 0 | +| annotation_gene | 46.7% | 0 | +| annotation_sbo | 81.7% | 0 |
Per-test scores @@ -93,7 +93,7 @@ _Full suite not run for this commit; comment_ `/run memote` _to add it._ _The score above is the fast core subset. Comment_ `/run memote` _to run the full suite on this pull request; the score updates here when it finishes._ -### [Gene essentiality (Hart 2015)](https://github.com/SysBioChalmers/Human-GEM/blob/fix/qc-comment-running-state/data/testResults/README.md#gene-essentiality-hart-2015) +### [Gene essentiality (Hart 2015)](https://github.com/SysBioChalmers/Human-GEM/blob/ci/results-push-and-salvage/data/testResults/README.md#gene-essentiality-hart-2015) _Not run automatically (it takes hours). Comment_ `/run gene-essentiality` _to run it on this pull request; the result posts as its own comment._