Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,27 @@ jobs:
codecov-token: ${{ secrets.CODECOV_TOKEN }}
dry-run: true

# The state this action exists to survive, and the one its own CI never reaches on its own: the
# merged report is NOT there. Every consumer is in it right now — an Actions storage quota is
# enforced at `CreateArtifact` before any bytes are sent, so nothing gets created — and this
# repository is public, so its storage is free and it can never reproduce that by accident.
#
# Naming an artifact that cannot exist reproduces it exactly. What is under test is not the
# message: it is that `continue-on-error` on a step of a COMPOSITE action is honoured at all, and
# that `steps.<id>.outcome` is readable from a later step of the same composite. If either is not
# true the action dies at the download exactly as before, and this job is the only thing that
# would say so.
action-absent-artifact:
name: The upload action survives a missing report
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: ./actions/upload-coverage
with:
codecov-token: ${{ secrets.CODECOV_TOKEN }}
artifact: testshards-lcov-deliberately-absent
dry-run: true

# The sharded path runs on one Julia version. Compatibility across the supported range is a
# different question, so it is asked separately and unsharded — a version matrix times a
# shard matrix would be 8N jobs to answer a question that does not need the split.
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "TestShards"
uuid = "acceef1d-f5e0-4fe4-a546-818dc56ce7b2"
version = "0.3.37"
version = "0.3.38"
authors = ["sota shimozono <shimozono-sota631@g.ecc.u-tokyo.ac.jp>"]

[deps]
Expand Down
42 changes: 39 additions & 3 deletions actions/upload-coverage/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,18 +116,54 @@ runs:
with:
submodules: ${{ inputs.submodules }}

- uses: actions/download-artifact@v8
# ABSENT and EMPTY are different states and get different treatment. This download is by
# `name:`, which HARD-FAILS when the artifact does not exist — unlike the workflow's own
# `pattern:` download, which succeeds with zero results. So an account that cannot create
# artifacts at all turned this job red at the download, before anything about coverage was
# even attempted:
#
# Unable to download artifact(s): Artifact not found for name: testshards-lcov
#
# An artifact that was never created is an infrastructure state — the run's own storage quota
# is enforced at `CreateArtifact`, before any bytes are sent, so no producer error is
# involved and there is nothing here to fix by failing. Losing the coverage REPORT is the
# correct degradation; losing the TEST RESULT to it is not.
- id: fetch
continue-on-error: true
uses: actions/download-artifact@v8
with:
name: ${{ inputs.artifact }}

# THE TRADE THIS MAKES, SAID OUT LOUD. `outcome != 'success'` is every reason the download can
# fail, not only absence — a network fault and a genuinely lost `-lcov` land here too. So a
# real regression in the producer degrades to a warning where it used to be red. That is
# accepted because the alternative is worse (a storage condition taking down every consumer's
# test result) and because the step summary carries it where a warning alone would be missed.
# What is NOT accepted is claiming a cause this step has not established: it says the download
# failed and lists what usually does that, rather than asserting the artifact does not exist.
- shell: bash
run: |
set -euo pipefail
[ -s lcov.info ] || { echo "::error::${{ inputs.artifact }} contained no lcov.info — did the sharded run finish with coverage on?"; exit 1; }
if [ "${{ steps.fetch.outcome }}" != "success" ]; then
echo "::warning::could not download ${{ inputs.artifact }}, so there is no merged report to send. Coverage is not reported for this run; the tests themselves are unaffected. The usual cause is that the run could not create artifacts at all — an Actions storage quota is enforced at CreateArtifact, before any bytes are sent, so it stops a 0-byte artifact exactly as it stops a large one. A lost upload or a transient fault reach this branch too, so check whether the run produced any artifacts at all before assuming the quota."
# `${GITHUB_STEP_SUMMARY:-}` because this runs under `set -u`, and an unbound variable
# here would kill the step in the middle of degrading gracefully — turning the fallback
# into a second, more confusing failure.
if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then
{
echo "### Coverage"
echo "Not reported: \`${{ inputs.artifact }}\` could not be downloaded."
} >> "$GITHUB_STEP_SUMMARY"
fi
exit 0
fi
# PRESENT BUT EMPTY is a different thing entirely: something produced the artifact and put
# no report in it. That is a producer bug and stays fatal.
[ -s lcov.info ] || { echo "::error::${{ inputs.artifact }} exists but contained no lcov.info — did the sharded run finish with coverage on?"; exit 1; }
echo "Merged report: $(grep -c '^SF:' lcov.info) source files."

- uses: codecov/codecov-action@v7
if: ${{ steps.token.outputs.have == 'true' }}
if: ${{ steps.token.outputs.have == 'true' && steps.fetch.outcome == 'success' }}
continue-on-error: ${{ inputs.fail-on-error != 'true' }}
with:
files: lcov.info
Expand Down
Loading