Skip to content

Commit

Permalink
Merge pull request containers#143 from cevich/skip_builds_by_label
Browse files Browse the repository at this point in the history
Skip specified image builds based on PR labels
  • Loading branch information
cevich authored Jul 1, 2022
2 parents f4068fd + 68a26cc commit dd99756
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ image_builder_task:
docker_arguments:
PACKER_VERSION: *PACKER_VERSION
env:
PACKER_BUILDS: 'image-builder'
# Google Application Credentials (JSON) with access to create VM images
GAC_JSON: ENCRYPTED[7fba7fb26ab568ae39f799ab58a476123206576b0135b3d1019117c6d682391370c801e149f29324ff4b50133012aed9]

Expand Down Expand Up @@ -246,6 +247,8 @@ imgts_task:
cpu: 2
memory: '2G'
env:
# Not all $IMGNAMES may have been built, don't fail if some are missing
REQUIRE_ALL: 0 # This should ONLY be set `0` on this repository!
BUILDID: "$CIRRUS_BUILD_ID"
REPOREF: "$CIRRUS_REPO_NAME"
GCPJSON: ENCRYPTED[112c55192dba9a7edd1889a7e704aa1e6ae40730b97ad8ebcbae2bb5f4ff84c7e9ca5b955baaf1f69e7b9e5c5a14a4d3]
Expand Down
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ magic strings in their *title* text:
* `[CI:TOOLING]` - Only perform validation steps, then [build and test
the tooling container images](README.md#tooling) only.

Additionally, you may use one/more [PR labels to disable certain
builds](README.md#bypassing-certain-builds).


# Building VM Images

Expand Down Expand Up @@ -83,6 +86,27 @@ please [see it's documentation page](https://www.packer.io/docs).
installing build & test dependencies, but also includes some
kernel and systemd services configuration.

## Bypassing certain builds

With a large number of VM and Container images to build, it's inevitable
that a flake will occur on an image the author does not care about. For
example, if you're building images *only* to update Buildah CI, you don't
care to produce the `fedora-netavark` VM image nor the `skopeo_cidev`
container image.

Should a flake occur on an build that's inconsequential to a specific
CI environment, there is a mechanism to bypass certain builds.

**Note**: This will *not* bypass container tooling images (they're always
required). Nor will it properly handle any build dependencies.
For example skipping a `fedora` build will cause a failure in
`build-push`(since it depends on the `fedora` base image).

To bypass a specific build, find a `no_<name>` GitHub label matching
the build name. Add that label to the PR and re-push or re-run a
previously failed build. It will then skip + automatically succeed.
Similarly, if you make a mistake with the labels, you can remove or
change them and re-run any affected tasks.

## The last part first (overview step 4)

Expand Down
4 changes: 4 additions & 0 deletions ci/make_base_images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ elif [[ -z "$IMG_SFX" ]] || [[ -z "$PACKER_BUILDS" ]]; then
die "Required non-empty values for \$IMG_SFX=$IMG_SFX and \$PACKER_BUILDS=$PACKER_BUILDS"
fi

if skip_on_pr_label; then
exit 0 # skip build
fi

set_gac_filepath
set_aws_filepath

Expand Down
4 changes: 4 additions & 0 deletions ci/make_cache_images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ elif [[ -z "$IMG_SFX" ]] || [[ -z "$PACKER_BUILDS" ]]; then
die "Required non-empty values for \$IMG_SFX=$IMG_SFX and \$PACKER_BUILDS=$PACKER_BUILDS"
fi

if skip_on_pr_label; then
exit 0 # skip build
fi

set_gac_filepath
set_aws_filepath

Expand Down
4 changes: 4 additions & 0 deletions ci/make_container_images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ if [[ "$CI" != "true" ]] || [[ "$CIRRUS_CI" != "$CI" ]]; then
die "Unexpected \$CI='$CI' and/or \$CIRRUS_CI='$CIRRUS_CI'"
fi

if skip_on_pr_label; then
exit 0 # skip build
fi

declare -a req_vars
req_vars=(\
IMG_SFX
Expand Down
4 changes: 4 additions & 0 deletions ci/make_image_builder.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ elif [[ -z "$IMG_SFX" ]]; then
die "Required non-empty values for \$IMG_SFX=$IMG_SFX"
fi

if skip_on_pr_label; then
exit 0 # skip build
fi

set_gac_filepath

set -exo pipefail
Expand Down
10 changes: 8 additions & 2 deletions imgts/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ ARGS="
[[ -n "$IMGNAMES" ]] || \
die 1 "No \$IMGNAMES were specified."

# Under some runtime conditions, not all images may be available
REQUIRE_ALL=${REQUIRE_ALL:-1}

# Don't allow one bad apple to ruin the whole batch
ERRIMGS=''

Expand All @@ -53,5 +56,8 @@ do
fi
done

[[ -z "$ERRIMGS" ]] || \
die 2 "ERROR: Failed to update one or more image timestamps: $ERRIMGS"
if [[ -n "$ERRIMGS" ]]; then
die_or_warn=die
((REQUIRE_ALL)) || die_or_warn=warn
$die_or_warn 2 "Failed to update one or more image timestamps: $ERRIMGS"
fi
9 changes: 9 additions & 0 deletions imgts/lib_entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ die() {
exit "$EXIT"
}

# Similar to die() but it ignores the first parameter (exit code)
# to allow direct use in place of an (otherwise) die() call.
warn() {
IGNORE=$1
shift
MSG="$*"
echo -e "${RED}WARNING: $MSG${NOR}"
}

# Hilight messages not coming from a shell command
msg() {
echo -e "${YEL}${1:-NoMessageGiven}${NOR}"
Expand Down
35 changes: 35 additions & 0 deletions lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,41 @@ set_aws_filepath() {
unset AWS_INI;
}

# Almost every CI-driven image build includes a `$PACKER_BUILDS`
# or `$TARTGET_NAME` specifier. Leverage appearance of a `no_*`
# PR-label prefix to bypass certain builds when running under CI.
skip_on_pr_label() {
req_env_vars AUTOMATION_LIB_PATH # Automation library is required

local build_spec pr_labels pr_label

if [[ -z "$CI" ]] || [[ "$CI" != 'true' ]]; then
warn "Skipping builds by PR-label only works under CI"
return 1 # reverse-logic: DO NOT SKIP
fi

build_spec="${TARGET_NAME:-$PACKER_BUILDS}"
pr_labels=$(get_pr_labels) # Will fail if not running under CI
if [[ -z "$build_spec" ]]; then
warn "Both \$TARGET_NAME and \$PACKER_BUILDS found empty, continuing anyway."
return 1
elif [[ -z "$pr_labels" ]]; then
warn "No labels found on PR, continuing with build."
return 1
fi

# N/B: Labels can contain spaces, assume maintainers are smart enough
# to not do this, or they're not important for this usage.
for pr_label in $pr_labels; do
if [[ "$pr_label" =~ no_.+ ]] && [[ "${pr_label#no_}" == "$build_spec" ]]; then
warn "Found '$pr_label' for '$build_spec', skipping build."
return 0 # reverse-logic: DO skip.
fi
dbg "Label '$pr_label' no match to '$build_spec'."
done
return 1 # Do not skip
}

# print a space-separated list of labels when run under Cirrus-CI for a PR
get_pr_labels() {
req_env_vars CIRRUS_CI CIRRUS_PR CIRRUS_REPO_CLONE_TOKEN
Expand Down

0 comments on commit dd99756

Please sign in to comment.