Skip to content

Feat: Permit soft-fail image builds - #13

Merged
tykeal merged 1 commit into
lfreleng-actions:mainfrom
modeseven-lfreleng-actions:feat/build-permit-fail
Aug 4, 2026
Merged

Feat: Permit soft-fail image builds#13
tykeal merged 1 commit into
lfreleng-actions:mainfrom
modeseven-lfreleng-actions:feat/build-permit-fail

Conversation

@ModeSevenIndustrialSolutions

Copy link
Copy Markdown
Contributor

Adds build_permit_fail to the verify lane, so repositories whose
Dockerfiles predate the current state of their upstream bases and
package feeds can adopt CI without gating review on breakage that
predates the change under test.

Why

A local probe of the Round 2 pilot, ONAP sdc/sdc-docker-base, built
1 of 6 images with completely unrestricted egress:

Image Base Result Root cause
base_sdc-cassandra cassandra:3.11.4 Debian stretch archived → apt-get update 404
base_sdc-cqlsh openjdk:8-jdk-alpine Base tag withdrawn from Docker Hub
base_sdc-jetty jetty:9.4.18-jre8-alpine chef:13.8.5bundler now needs Ruby ≥ 3.2; image ships 2.5
base_sdc-python nexus3.onap.org:10001/onap/integration-python:8.0.0 apk pin ruby=2.7.5-r0 unsatisfiable
base_sdc-sanity openjdk:8-jdk-alpine Base tag withdrawn
base_sdc-vnc consol/ubuntu-xfce-vnc:1.3.0

The base_sdc-jetty failure had looked like an egress-block problem in
earlier CI (rubygems.org ECONNREFUSED). It is not:
build_permit_egress_traffic: true does not rescue it, because once
RubyGems is reachable it resolves a bundler the image's Ruby cannot
run. Gating Gerrit on that build would place a permanent Verified -1 on
every change to the repository.

What changed

  • The build job attempts every image rather than aborting at the
    first failure, collecting successes and failures separately and
    gating at the end on build_permit_fail. Images that do build carry
    on to the test, SBOM and scan jobs, so partial coverage stays useful.
    Dockerfile lint is unaffected, having never needed a build.
  • The build_command path gets the same treatment: a non-zero command
    is recorded rather than fatal, and "exited zero but created nothing"
    reports once rather than twice.
  • Building nothing is now a supported outcome. image_count guards the
    archive upload and the tests/sbom job conditions, so
    if-no-files-found: error still catches a genuine export failure;
    grype skips through sbom.
  • The step summary lists images that failed alongside those that built,
    and outputs land before the gate so both stay visible either way.

build_permit_fail deliberately takes no repository variable
fallback, unlike audit_permit_fail/grype_permit_fail which honour
NO_BLOCK_AUDIT_FAIL. A variable meant for audit findings must not
switch off build gating across an organisation.

Self-test

New matrix leg 5 pairs a buildable fixture image with one declaring a
stage the Dockerfile does not define, under build_permit_fail: true.
It proves the failure is reported, the job succeeds, and the image that
built still reaches SBOM/Grype — without touching the fixture repo.

Validated with pre-commit (all pass), zizmor --persona auditor (no
findings), and bash -n plus shellcheck over every extracted run
block.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a build_permit_fail input to the reusable Docker verify lane so image build failures can be recorded and summarized while still allowing successfully-built images to proceed to tests/SBOM/Grype, with downstream jobs safely skipped when zero images were built.

Changes:

  • Introduces build_permit_fail workflow_call input and uses it to gate build failures at the end of the build step (instead of failing fast).
  • Makes build output handling robust when zero images are produced (skips archive upload and downstream jobs via image_count).
  • Updates the self-test matrix and README to document and validate the new behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
README.md Documents the new build_permit_fail input and its intent.
.github/workflows/testing.yaml Adds a new self-test matrix leg covering permitted build failures.
.github/workflows/build-test.yaml Implements soft-fail build behavior, summaries, and downstream skipping when no images are built.
Suppressed comments (1)

.github/workflows/build-test.yaml:666

  • This warning message says “image(s) failed to build”, but the failures list can also include non-image entries (e.g., "build_command"). Consider wording that doesn’t assume every failure is an image build.
            echo "::warning::${#failures[@]} image(s) failed to" \
              "build; permitted by build_permit_fail"

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/build-test.yaml
Repositories whose Dockerfiles predate the current state of their
upstream bases and package feeds cannot pass a gating build. A
probe of ONAP sdc/sdc-docker-base built 1 of 6 images: two bases
have left Docker Hub, one apt suite is archived, one apk pin is
unsatisfiable, and the chef gem no longer resolves on the Ruby the
image ships. Gating Gerrit on that build would place a permanent
Verified -1 on every change, punishing contributors for breakage
that predates the change under test.

The build job now attempts every image, records which fail, and
gates on the outcome through build_permit_fail, matching the
test/audit/grype soft-fail family the lane already carries. The
images that do build carry on to the test, SBOM and scan jobs, so
partial coverage stays useful, and Dockerfile lint is unaffected
because it never needed a build. Unlike the audit toggles this
input takes no repository variable fallback: build gating must not
switch off across an organisation by accident.

A build that produces nothing is now a supported outcome, so the
archive upload and the test/SBOM jobs check the image count rather
than assuming an artifact exists.

Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Matthew Watkins <mwatkins@linuxfoundation.org>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (2)

README.md:91

  • This documentation says the input only permits “image build failures”, but the workflow also records and gates on build_command failures via the failures list. The description should reflect that build_permit_fail applies to both native image builds and the build_command escape hatch.
| `build_permit_fail`           | boolean | `false`    | Permit image build failures; images that build carry on downstream   |

.github/workflows/build-test.yaml:99

  • The input description says it permits “image build failures”, but the implementation also permits failures of the build_command escape hatch (it adds the build_command sentinel to the failures array and gates on it). Update the description so callers understand this input covers both paths.
        description: >-
          Permit image build failures without failing the workflow.
          Intended for repositories whose Dockerfiles predate the
          current state of their upstream bases and package feeds:
          the lane still lints every Dockerfile and reports which

@tykeal
tykeal merged commit 122fc12 into lfreleng-actions:main Aug 4, 2026
49 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants