diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml new file mode 100644 index 0000000000..8a8916d45c --- /dev/null +++ b/.github/actionlint.yaml @@ -0,0 +1,8 @@ +self-hosted-runner: + labels: + - oracle-vm-2cpu-8gb-x86-64 + - oracle-vm-4cpu-16gb-x86-64 + - oracle-vm-8cpu-32gb-x86-64 + - oracle-vm-16cpu-64gb-x86-64 + - oracle-vm-24cpu-96gb-x86-64 + - oracle-vm-32cpu-128gb-x86-64 diff --git a/.github/filters.yaml b/.github/filters.yaml new file mode 100644 index 0000000000..3b4fd7de1f --- /dev/null +++ b/.github/filters.yaml @@ -0,0 +1,29 @@ +# Path filters for .github/workflows/ci.yml, consumed by dorny/paths-filter. +# When a PR touches none of `all` or `code`, the heavier optional jobs +# (cross/osx/ostree_rs_ext) are skipped. validate/doccheck/test_skopeo always +# run regardless. + +# Anything that should invalidate every skip decision. +all: + - '.github/workflows/ci.yml' + - '.github/filters.yaml' + - 'Makefile' + - 'hack/**' + - 'vendor/**' + - 'go.mod' + - 'go.sum' + +# Production Go source. Tests and bats are excluded so a test-only diff +# does not force every "code" gated job to run. +code: + - '**/*.go' + - '!**/*_test.go' + - '!systemtest/**' + - '!integration/**' + +# Docs-only signal kept for symmetry. Not directly gated on; the run rule is +# "all OR code matched", so a pure-docs change naturally skips heavy jobs. +docs: + - 'docs/**' + - 'docs-experimental/**' + - '**/*.md' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..0738515239 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,211 @@ +name: CI + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + path-filter: + runs-on: ubuntu-latest + timeout-minutes: 5 + outputs: + all: ${{ steps.filter.outputs.all }} + code: ${{ steps.filter.outputs.code }} + docs: ${{ steps.filter.outputs.docs }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 + id: filter + with: + filters: .github/filters.yaml + + validate: + runs-on: oracle-vm-4cpu-16gb-x86-64 + timeout-minutes: 45 + container: + image: quay.io/libpod/skopeo_cidev:c20260310t170224z-f43f42d14 # FIXME: Should be Renovate-managed. + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - name: fix git safe.directory + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + - run: make tools + - run: make validate-local + - name: vendor + tree status + run: | + make vendor + hack/tree_status.sh + + doccheck: + needs: validate + runs-on: oracle-vm-4cpu-16gb-x86-64 + timeout-minutes: 45 + container: + image: quay.io/libpod/skopeo_cidev:c20260310t170224z-f43f42d14 # FIXME: Should be Renovate-managed. + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - name: fix git safe.directory + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + - name: remove pre-installed skopeo package + run: dnf remove -y skopeo + - name: build + install + run: | + make BUILDTAGS=containers_image_openpgp bin/skopeo + make BUILDTAGS=containers_image_openpgp install PREFIX=/usr/local + - run: make BUILDTAGS=containers_image_openpgp validate-docs + + cross: + needs: [validate, path-filter] + if: >- + !contains(github.event.pull_request.title || github.event.head_commit.message, '[CI:DOCS]') + && (github.event_name != 'pull_request' + || needs.path-filter.outputs.all == 'true' + || needs.path-filter.outputs.code == 'true') + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version: stable + - run: make BUILDTAGS=containers_image_openpgp local-cross + + osx: + needs: [validate, path-filter] + if: >- + !contains(github.event.pull_request.title || github.event.head_commit.message, '[CI:DOCS]') + && (github.event_name != 'pull_request' + || needs.path-filter.outputs.all == 'true' + || needs.path-filter.outputs.code == 'true') + runs-on: macos-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version: stable + - name: configure GOPATH (Makefile resolves GOBIN as $(GOPATH)/bin) + run: | + GOPATH="$(go env GOPATH)" + mkdir -p "$GOPATH/bin" + echo "GOPATH=$GOPATH" >> "$GITHUB_ENV" + echo "$GOPATH/bin" >> "$GITHUB_PATH" + - name: brew install gpgme (CGo dep for github.com/proglottis/gpgme) + run: brew install gpgme + - run: make tools + - run: make validate-local test-unit-local bin/skopeo + - run: ./bin/skopeo -v + + test_skopeo: + needs: validate + if: >- + !contains(github.event.pull_request.title || github.event.head_commit.message, '[CI:DOCS]') + && !contains(github.event.pull_request.title || github.event.head_commit.message, '[CI:BUILD]') + runs-on: oracle-vm-2cpu-8gb-x86-64 + timeout-minutes: 45 + name: test_skopeo / ${{ matrix.name }} + strategy: + fail-fast: false + matrix: + include: + - name: Skopeo Test + buildtags: "" + - name: Skopeo Test w/ openpgp + buildtags: containers_image_openpgp + - name: Skopeo Test w/ Sequoia + buildtags: containers_image_sequoia + container: + image: quay.io/libpod/skopeo_cidev:c20260310t170224z-f43f42d14 # FIXME: Should be Renovate-managed. + options: --privileged + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - name: fix git safe.directory + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + - run: make vendor + - name: build + install + run: | + make "BUILDTAGS=${{ matrix.buildtags }}" bin/skopeo + make "BUILDTAGS=${{ matrix.buildtags }}" install PREFIX=/usr/local + - run: make "BUILDTAGS=${{ matrix.buildtags }}" test-unit-local + - run: make "BUILDTAGS=${{ matrix.buildtags }}" test-integration-local + - run: make "BUILDTAGS=${{ matrix.buildtags }}" test-system-local + + ostree_rs_ext: + needs: [validate, path-filter] + if: >- + !contains(github.event.pull_request.title || github.event.head_commit.message, '[CI:DOCS]') + && (github.event_name != 'pull_request' + || needs.path-filter.outputs.all == 'true' + || needs.path-filter.outputs.code == 'true') + runs-on: oracle-vm-4cpu-16gb-x86-64 + timeout-minutes: 45 + container: + image: quay.io/coreos-assembler/fcos-buildroot:testing-devel + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - name: fix git safe.directory + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + - name: install rustup stable + run: | + dnf remove -y rust + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal + echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" + - name: build + install skopeo + run: | + dnf builddep -y skopeo + make + make install + - name: clone ostree-rs-ext + cargo build + run: | + git clone --depth 1 https://github.com/ostreedev/ostree-rs-ext.git /tmp/ostree-rs-ext + cd /tmp/ostree-rs-ext + cargo test --no-run + - name: cargo test + run: | + cd /tmp/ostree-rs-ext + cargo test -- --nocapture --quiet + + # Merge protection is set up for this job name, do not change it. + success: + name: "Total Success" + needs: + - path-filter + - validate + - doccheck + - cross + - osx + - test_skopeo + - ostree_rs_ext + if: always() + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Check all required jobs + run: | + if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]] || \ + [[ "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then + echo "One or more required jobs failed or were cancelled" + exit 1 + fi + echo "All required jobs passed or were skipped" diff --git a/.packit.yaml b/.packit.yaml index 82fcf8cc09..29d4a85580 100644 --- a/.packit.yaml +++ b/.packit.yaml @@ -4,7 +4,7 @@ # NOTE: The Packit copr_build tasks help to check if every commit builds on # supported Fedora and CentOS Stream arches. -# They do not block the current Cirrus-based workflow. +# They do not block the GitHub Actions PR workflow. downstream_package_name: skopeo upstream_tag_template: v{version} diff --git a/Makefile b/Makefile index be5a33355d..ecc63c651f 100644 --- a/Makefile +++ b/Makefile @@ -68,10 +68,11 @@ CI ?= # modify local configuration files and services. export SKOPEO_CONTAINER_TESTS ?= $(if $(CI),1,0) -# This is a compromise, we either use a container for this or require -# the local user to have a compatible python3 development environment. -# Define it as a "resolve on use" variable to avoid calling out when possible -SKOPEO_CIDEV_CONTAINER_FQIN ?= $(shell hack/get_fqin.sh) +# Container image used by the test-integration / test-system wrapper targets. +# Set this to a skopeo_cidev image (e.g. quay.io/libpod/skopeo_cidev:) +# when running those targets locally. If unset, the wrapper targets will fail +# loudly with an empty image reference. +SKOPEO_CIDEV_CONTAINER_FQIN ?= CONTAINER_CMD ?= ${CONTAINER_RUNTIME} run --rm -i -e TESTFLAGS="$(TESTFLAGS)" -e CI=$(CI) -e SKOPEO_CONTAINER_TESTS=1 # if this session isn't interactive, then we don't want to allocate a # TTY, which would fail, but if it is interactive, we do want to attach @@ -106,7 +107,7 @@ endif all: bin/skopeo docs codespell: - codespell -S Makefile,build,buildah,buildah.spec,imgtype,copy,AUTHORS,bin,vendor,.git,go.sum,CHANGELOG.md,changelog.txt,seccomp.json,.cirrus.yml,"*.xz,*.gz,*.tar,*.tgz,*ico,*.png,*.1,*.5,*.orig,*.rej" -L fpr,uint,iff,od,ERRO -w + codespell -S Makefile,build,buildah,buildah.spec,imgtype,copy,AUTHORS,bin,vendor,.git,go.sum,CHANGELOG.md,changelog.txt,seccomp.json,"*.xz,*.gz,*.tar,*.tgz,*ico,*.png,*.1,*.5,*.orig,*.rej" -L fpr,uint,iff,od,ERRO -w help: @echo "Usage: make " diff --git a/hack/get_ci_vm.sh b/hack/get_ci_vm.sh deleted file mode 100755 index 0073bad3da..0000000000 --- a/hack/get_ci_vm.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash - -# -# For help and usage information, simply execute the script w/o any arguments. -# -# This script is intended to be run by Red Hat skopeo developers who need -# to debug problems specifically related to Cirrus-CI automated testing. -# It requires that you have been granted prior access to create VMs in -# google-cloud. For non-Red Hat contributors, VMs are available as-needed, -# with supervision upon request. - -set -e - -SCRIPT_FILEPATH=$(realpath "${BASH_SOURCE[0]}") -SCRIPT_DIRPATH=$(dirname "$SCRIPT_FILEPATH") -REPO_DIRPATH=$(realpath "$SCRIPT_DIRPATH/../") - -# Help detect if we were called by get_ci_vm container -GET_CI_VM="${GET_CI_VM:-0}" -in_get_ci_vm() { - if ((GET_CI_VM==0)); then - echo "Error: $1 is not intended for use in this context" - exit 2 - fi -} - -# get_ci_vm APIv1 container entrypoint calls into this script -# to obtain required repo. specific configuration options. -if [[ "$1" == "--config" ]]; then - in_get_ci_vm "$1" - cat < /dev/stderr - ${GOSRC}/${SCRIPT_BASE}/runner.sh setup -else - # Create and access VM for specified Cirrus-CI task - mkdir -p $HOME/.config/gcloud/ssh - podman run -it --rm \ - --tz=local \ - -e NAME="$USER" \ - -e SRCDIR=/src \ - -e GCLOUD_ZONE="$GCLOUD_ZONE" \ - -e DEBUG="${DEBUG:-0}" \ - -v $REPO_DIRPATH:/src:O \ - -v $HOME/.config/gcloud:/root/.config/gcloud:z \ - -v $HOME/.config/gcloud/ssh:/root/.ssh:z \ - quay.io/libpod/get_ci_vm:latest "$@" -fi diff --git a/hack/get_fqin.sh b/hack/get_fqin.sh deleted file mode 100755 index 8076d10dad..0000000000 --- a/hack/get_fqin.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -# This script is intended to be called from the Makefile. It's purpose -# is to automation correspondence between the environment used for local -# development and CI. - -set -e - -SCRIPT_FILEPATH=$(realpath "${BASH_SOURCE[0]}") -SCRIPT_DIRPATH=$(dirname "$SCRIPT_FILEPATH") -REPO_DIRPATH=$(realpath "$SCRIPT_DIRPATH/../") - -# When running under CI, we already have the necessary information, -# simply provide it to the Makefile. -if [[ -n "$SKOPEO_CIDEV_CONTAINER_FQIN" ]]; then - echo "$SKOPEO_CIDEV_CONTAINER_FQIN" - exit 0 -fi - -if [[ -n $(command -v podman) ]]; then CONTAINER_RUNTIME=podman; fi -CONTAINER_RUNTIME=${CONTAINER_RUNTIME:-docker} - -# Borrow the get_ci_vm container image since it's small, and -# by necessity contains a script that can accurately interpret -# env. var. values from any .cirrus.yml runtime context. -$CONTAINER_RUNTIME run --rm \ - --security-opt label=disable \ - -v $REPO_DIRPATH:/src:ro \ - --entrypoint=/usr/share/automation/bin/cirrus-ci_env.py \ - quay.io/libpod/get_ci_vm:latest \ - --envs="Skopeo Test" /src/.cirrus.yml | \ - grep -E -m1 '^SKOPEO_CIDEV_CONTAINER_FQIN' | \ - awk -F "=" -e '{print $2}' | \ - tr -d \'\"