发布

  • [OPIK-6624] [CI] fix(release): skip on 403 "cannot publish over" instead of failing (#6797)

    frostbyte_neo 发布于 2026-05-20 13:26:19 +00:00

    • [OPIK-6624] [CI] fix(release): skip on 403 cannot publish over instead of failing

    When npm publish returns 403 with "You cannot publish over the previously
    published versions: X.Y.Z", the version is already in the registry and
    retrying produces the same error — the desired end state is already achieved.
    Treat this as a skip-with-warning instead of failing CI after 3 attempts.

    Triggered by the 2026-05-20 re-dispatch of opik@2.0.42 (run #26149349373):
    after NPM_TOKEN was rotated, the workflow was retriggered, but 2.0.42 had
    already been published by a concurrent run at 12:22:13 UTC. The retry loop
    hammered the same 403 three times and failed the job.

    Mechanics:

    • Capture publish output via tee to a tmpfile (streams live AND inspects).
    • After failure, grep for E403 + cannot publish over (case-insensitive).
    • If matched: emit a clear ::warning:: and break out of the retry loop with
      ALREADY_PUBLISHED=true. Downstream env exports still run, so the Summary
      step works normally.
    • If not matched: keep current retry behavior (transient errors still retry).

    Race-safety: catching the 403 after the publish attempt closes the
    classic check-then-publish race that a naive pre-check has. We only see this
    error after another run has won; that's exactly the safe condition to no-op.

    • fix(ci/publish): capture PIPESTATUS[0] explicitly, don't rely on pipefail

    Per review on PR #6797: the previous if timeout $TIMEOUT_SECONDS $PUBLISH_CMD 2>&1 | tee "$PUBLISH_LOG"; then evaluated the pipeline's overall exit status.
    On GitHub Actions with shell: bash, pipefail is on by default — so the
    behaviour was correct as-shipped — but the code's comment claimed it was
    checking PIPESTATUS[0], which it wasn't.

    Refactor to do what the comment claimed: run the pipeline, capture
    EXIT_CODE=${PIPESTATUS[0]} immediately, and branch on $EXIT_CODE. No
    hidden dependency on set -o pipefail, no surprises if the step's shell
    gets switched or the script is exercised locally with stock bash.

    Identical behaviour:

    • exit 0 -> SUCCESS=true, break
    • exit 124 -> "timed out", evaluate 403-skip, retry/fail
    • any other -> "failed with exit code N", evaluate 403-skip, retry/fail
    下载附件