diff --git a/.ci/gpg/create-keyring.sh b/.ci/gpg/create-keyring.sh index a7f1dce9b1..7837e313ea 100755 --- a/.ci/gpg/create-keyring.sh +++ b/.ci/gpg/create-keyring.sh @@ -18,7 +18,7 @@ cp "${DIR}"/*.auto* "${GPG_HOME}" echo -e "\nDecrypting secret key..." { - # $GPG_PASSWORD is taken from the script's env (injected by Travis CI). + # $GPG_PASSWORD is taken from the script's env (injected by CI). echo $GPG_PASSWORD | gpg --decrypt \ --pinentry-mode loopback --batch \ --passphrase-fd 0 \ diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000000..b38b8284ae --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,99 @@ +name: deploy + +on: + push: + branches: + - '**' + tags: + - 'v*' + pull_request: + branches: [ master ] + +jobs: + # Job to test release steps. This will only create a release remotely if run on a tagged commit. + goreleaser: + name: goreleaser + runs-on: ubuntu-18.04 + environment: deploy + steps: + - name: checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: install + uses: actions/setup-go@v2 + with: + go-version: 1.15.5 + + - name: gpg init + if: github.event_name != 'pull_request' + run: .ci/gpg/create-keyring.sh + env: + GPG_PASSWORD: ${{ secrets.GPG_PASSWORD }} + + - name: release + run: | + if [[ $GITHUB_REF != refs/tags/* ]]; then + export DRY_RUN=1 + fi + make release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Job matrix for image builds. + images: + name: images + runs-on: ubuntu-18.04 + environment: deploy + strategy: + matrix: + id: ["operator-sdk", "ansible-operator", "helm-operator", "scorecard-test", "scorecard-test-kuttl"] + steps: + + - name: set up qemu + uses: docker/setup-qemu-action@v1 + + - name: set up buildx + uses: docker/setup-buildx-action@v1 + + - name: quay.io login + if: github.event_name != 'pull_request' + uses: docker/login-action@v1 + with: + username: ${{ secrets.QUAY_USERNAME }} + password: ${{ secrets.QUAY_PASSWORD }} + registry: quay.io + + - name: create tags + id: tags + run: | + IMG=quay.io/operator-framework/${{ matrix.id }} + if [[ $GITHUB_REF == refs/tags/* ]]; then + TAG=${GITHUB_REF#refs/tags/} + MAJOR_MINOR=${TAG%.*} + echo ::set-output name=tags::${IMG}:${TAG},${IMG}:${MAJOR_MINOR} + + elif [[ $GITHUB_REF == refs/heads/* ]]; then + TAG=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g') + echo ::set-output name=tags::${IMG}:${TAG} + + elif [[ $GITHUB_REF == refs/pull/* ]]; then + TAG=pr-${{ github.event.number }} + echo ::set-output name=tags::${IMG}:${TAG} + fi + + - name: checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: build and push + uses: docker/build-push-action@v2 + with: + file: ./images/${{ matrix.id }}/Dockerfile + context: . + # s390x is not supported by the scorecard-test-kuttl base image. + platforms: linux/amd64,linux/arm64,linux/ppc64le${{ matrix.id != 'scorecard-test-kuttl' && ',linux/s390x' || '' }} + push: ${{ (github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/') || github.ref == format('refs/heads/{0}', github.event.repository.default_branch) )) }} + tags: ${{ steps.tags.outputs.tags }} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5d2658e424..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,166 +0,0 @@ -os: linux -dist: xenial - -language: go -go: -- 1.15.5 -go_import_path: github.com/operator-framework/operator-sdk - -cache: - directories: - - ${HOME}/.cache/go-build - - $(go env GOPATH)/pkg/mod - -# The `x_base_steps` top-level key is unknown to travis, -# so we can use it to create a bunch of common build step -# YAML anchors which we use in our build jobs. -x_base_steps: - # Base go, ansbile, and helm job - - &test - before_install: - # hack/ci/check-doc-only-update.sh needs to be sourced so - # that it can properly exit the test early with success - - source hack/ci/check-doc-only-update.sh "$TRAVIS_COMMIT_RANGE" - - git fetch origin --unshallow --tags - after_failure: - - kubectl get all --all-namespaces - - kubectl get events --all-namespaces --field-selector=type=Warning - services: - - docker - - # Base deploy job - - &deploy - before_install: - - git fetch origin --unshallow --tags - services: - - docker - - # Manifest list deploy job - - &manifest-deploy - before_script: - - git fetch origin --unshallow --tags - # TODO: remove the chmod command when docker-ce on travis is upgraded to 18.09.0+. - # We need /etc/docker to be accessible to non-root users. - # See https://github.com/moby/moby/pull/37847. - - sudo chmod 0755 /etc/docker - services: - - docker - -stages: - - name: check - if: type == pull_request - - name: test - if: type == pull_request - - name: deploy - if: type != pull_request AND ( tag IS present OR branch = master OR commit_message =~ /\[travis deploy\]/ ) - - name: deploy-manifest-multiarch - if: type != pull_request AND ( tag IS present OR branch = master OR commit_message =~ /\[travis deploy\]/ ) - - name: release - if: type != pull_request AND tag IS present - -jobs: - include: - - ## Project check stage jobs ## - - # Run the sanity tests - - stage: check - name: sanity - before_install: - - git fetch origin --unshallow --tags - script: - - make test-sanity - - # Run website checks - - name: docs - script: - - make test-docs - - ## Operator test stage jobs ## - - # Build and test ansible and test ansible using molecule - - stage: test - name: ansible e2e - <<: *test - env: - # Required to set python3 as the default python interpreter. - - PATH=/opt/python/3.6.7/bin:${PATH} - before_script: - - sudo apt-get install python3 python3-pip - - pip3 install --upgrade setuptools pip - - pip install --user ansible~=2.9.13 - script: - - make test-e2e-ansible test-e2e-ansible-molecule - - # Test subcommands - - name: subcommand and integration - <<: *test - script: - - make test-e2e-integration - - # Build and test go - - name: go unit and e2e - <<: *test - before_script: - - (cd / && go get github.com/mattn/goveralls) - script: - - make test-unit - - make test-e2e-go - after_success: - - $GOPATH/bin/goveralls -service=travis-ci -coverprofile=coverage.out -repotoken=$COVERALLS_TOKEN - - # Build and test helm - - name: helm e2e - <<: *test - script: make test-e2e-helm - - ## Image deploy/push stage jobs ## - - # Build and deploy arm64 docker images - - stage: deploy - name: build and push images - arch: arm64 - <<: *deploy - script: - - make image-build - - make -f release/Makefile image-push - - # Build and deploy amd64 docker images - - name: build and push images - arch: amd64 - <<: *deploy - script: - - make image-build - - make -f release/Makefile image-push - - # Build and deploy ppc64le docker images - - name: build and push images - arch: ppc64le - <<: *deploy - script: - - make image-build - - make -f release/Makefile image-push - - # Build and deploy s390x docker images - - name: build and push images - arch: s390x - <<: *deploy - script: - # Use targets directly since kuttl doesn't support s390x. - - make image/ansible-operator image/helm-operator image/operator-sdk image/scorecard-test - - make -f release/Makefile image-push/ansible-operator image-push/helm-operator image-push/operator-sdk image-push/scorecard-test - - # Build and deploy ansible multi-arch manifest list - - stage: deploy-manifest-multiarch - name: push manifest lists - <<: *manifest-deploy - script: make -f release/Makefile image-push-multiarch - - ## Release jobs ## - - - stage: release - name: publish release - before_install: git fetch origin --unshallow --tags - install: sudo ln -sf $(command -v gpg2) $(dirname $(command -v gpg2))/gpg - before_script: .ci/gpg/create-keyring.sh - script: make release diff --git a/Makefile b/Makefile index ddc84a5e93..41d824c39f 100644 --- a/Makefile +++ b/Makefile @@ -66,13 +66,14 @@ build: ## Build operator-sdk, ansible-operator, and helm-operator. @mkdir -p $(BUILD_DIR) go build $(GO_BUILD_ARGS) -o $(BUILD_DIR) ./cmd/{operator-sdk,ansible-operator,helm-operator} +.PHONY: build/operator-sdk build/ansible-operator build/helm-operator +build/operator-sdk build/ansible-operator build/helm-operator: + go build $(GO_BUILD_ARGS) -o $(BUILD_DIR)/$(@F) ./cmd/$(@F) + # Build scorecard binaries. .PHONY: build/scorecard-test build/scorecard-test-kuttl build/custom-scorecard-tests build/scorecard-test build/scorecard-test-kuttl build/custom-scorecard-tests: go build $(GO_GCFLAGS) $(GO_ASMFLAGS) -o $(BUILD_DIR)/$(@F) ./images/$(@F) -.PHONY: build/operator-sdk build/ansible-operator build/helm-operator -build/operator-sdk build/ansible-operator build/helm-operator: - go build $(GO_BUILD_ARGS) -o $(BUILD_DIR)/$(@F) ./cmd/$(@F) ##@ Dev image build @@ -83,13 +84,13 @@ image-build: $(foreach i,$(IMAGE_TARGET_LIST),image/$(i)) ## Build all images. # Build an image. BUILD_IMAGE_REPO = quay.io/operator-framework -image/%: BUILD_DIR = build/_image -# Images run on the linux kernel, so binaries must always target linux. -image/%: export GOOS = linux -image/%: build/% - mkdir -p ./images/$*/bin && mv $(BUILD_DIR)/$* ./images/$*/bin - docker build -t $(BUILD_IMAGE_REPO)/$*:dev -f ./images/$*/Dockerfile ./images/$* - rm -rf $(BUILD_DIR) +# When running in a terminal, this will be false. If true (ex. CI), print plain progress. +ifneq ($(shell test -t 0; echo $$?),0) +DOCKER_PROGRESS = --progress plain +endif +image/%: export DOCKER_CLI_EXPERIMENTAL = enabled +image/%: + docker buildx build $(DOCKER_PROGRESS) -t $(BUILD_IMAGE_REPO)/$*:dev -f ./images/$*/Dockerfile --load . ##@ Release diff --git a/README.md b/README.md index 13f6aeb14c..1ad217c59d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ -[![Build Status](https://travis-ci.com/operator-framework/operator-sdk.svg?branch=master)](https://travis-ci.com/operator-framework/operator-sdk) + + [![License](http://img.shields.io/:license-apache-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) [![Go Report Card](https://goreportcard.com/badge/github.com/operator-framework/operator-sdk)](https://goreportcard.com/report/github.com/operator-framework/operator-sdk) diff --git a/hack/ci/check-doc-only-update.sh b/hack/ci/check-doc-only-update.sh index 5bc6b9ad48..a3788004f0 100755 --- a/hack/ci/check-doc-only-update.sh +++ b/hack/ci/check-doc-only-update.sh @@ -3,7 +3,6 @@ set -e # If running in Github actions: this should be set to "github.base_ref". -# If running in Travis CI: this should be set to "$TRAVIS_COMMIT_RANGE". : ${1?"the first argument must be set to a commit-ish reference"} # Patterns to ignore. diff --git a/hack/image/push-image-tags.sh b/hack/image/push-image-tags.sh deleted file mode 100755 index b47b059361..0000000000 --- a/hack/image/push-image-tags.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash -source hack/lib/image_lib.sh - -# -# push_image_tags -# -# push_image_tags tags the source docker image with zero or more -# image tags based on TravisCI environment variables and the -# presence of git tags in the repository of the current working -# directory. If a second argument is present, it will be used as -# the base image name in pushed image tags. -# -function push_image_tags() { - - source_image=$1; shift || fatal "${FUNCNAME} usage error" - push_image=$1; shift || push_image=$source_image - - print_image_info $source_image - - docker_login $push_image - - check_can_push || return 0 - - images=$(get_image_tags $push_image) - - for image in $images; do - docker tag "$source_image" "$image" - docker push "$image" - done -} - -# -# print_image_info -# -# print_image_info prints helpful information about a docker -# image. -# -function print_image_info() { - image_name=$1; shift || fatal "${FUNCNAME} usage error" - image_id=$(docker inspect "$image_name" -f "{{.Id}}") - image_created=$(docker inspect "$image_name" -f "{{.Created}}") - - if [[ -n "$image_id" ]]; then - echo "Docker image info:" - echo " Name: $image_name" - echo " ID: $image_id" - echo " Created: $image_created" - echo "" - else - echo "Could not find docker image \"$image_name\"" - return 1 - fi -} - -push_image_tags "$@" diff --git a/hack/image/push-manifest-list.sh b/hack/image/push-manifest-list.sh deleted file mode 100755 index b3af06942a..0000000000 --- a/hack/image/push-manifest-list.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash - -source hack/lib/image_lib.sh - -# -# push_manifest_list [ ] -# -# push_manifest_list uses the pre-pushed images for each -# supported architecture and pushes a manifest list for each -# of the tags from the Travis CI envionment (created during -# the image push job). -# -function push_manifest_list() { - push_image=$1; shift || fatal "${FUNCNAME} usage error" - arches=$@ - - docker_login $push_image - - check_can_push || return 0 - - tags=$(get_image_tags) - for tag in $tags; do - images_with_arches=$(get_arch_images $push_image $tag $arches) - DOCKER_CLI_EXPERIMENTAL="enabled" docker manifest create $push_image:$tag $images_with_arches - DOCKER_CLI_EXPERIMENTAL="enabled" docker manifest push --purge $push_image:$tag - done - -} - -function get_arch_images(){ - image=$1; shift || fatal "${FUNCNAME} usage error" - tag=$1; shift || fatal "${FUNCNAME} usage error" - arches="$@" - for arch in $arches; do - echo "$image-$arch:$tag" - done -} - -push_manifest_list "$@" diff --git a/hack/lib/image_lib.sh b/hack/lib/image_lib.sh deleted file mode 100755 index e8acfa0281..0000000000 --- a/hack/lib/image_lib.sh +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env bash - -source hack/lib/common.sh - -semver_regex="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$" - -# docker_login -# -# docker_login performs a docker login for the server of the provided -# image if the DOCKER_USERNAME and DOCKER_PASSWORD environment variables -# are set. -# -function docker_login() { - image_name=$1; shift || fatal "${FUNCNAME} usage error" - - if [[ -n "$DOCKER_USERNAME" && -n "$DOCKER_PASSWORD" ]]; then - server=$(docker_server_for_image $image_name) - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin "$server" - fi -} - -# -# check_can_push -# -# check_can_push performs various checks to determine whether images -# built from this commit should be pushed. It prints a message and -# returns a failure code if any check doesn't pass. -# -function check_can_push() { - if [[ "$TRAVIS" != "true" ]]; then - echo "Detected execution in a non-TravisCI environment. Skipping image push." - return 1 - elif [[ "$TRAVIS_EVENT_TYPE" == "pull_request" ]]; then - echo "Detected pull request commit. Skipping image push" - return 1 - elif [[ ! -f "$HOME/.docker/config.json" ]]; then - echo "Docker login credentials required to push. Skipping image push." - return 1 - fi -} - -# -# get_image_tags -# -# get_image_tags returns a list of tags that are eligible to be pushed. -# If an image name is passed as an argument, the full : will -# be returned for each eligible tag. The criteria is: -# 1. Is TRAVIS_BRANCH set? => :$TRAVIS_BRANCH -# 2. Is TRAVIS_TAG highest semver release? => :latest -# -function get_image_tags() { - image_name=$1 - [[ -n "$image_name" ]] && image_name="${image_name}:" - - # Tag `:$TRAVIS_BRANCH` if it is set. - # Note that if the build is for a tag, $TRAVIS_BRANCH is set - # to the tag, so this works in both cases - if [[ -n "$TRAVIS_BRANCH" ]]; then - echo "${image_name}${TRAVIS_BRANCH}" - fi - - # Tag `:latest` if $TRAVIS_TAG is the highest semver tag found in - # the repository. - if is_latest_tag "$TRAVIS_TAG"; then - echo "${image_name}latest" - fi -} - -# -# docker_server_for_image -# -# docker_server_for_image returns the server component of the image -# name. If the image name does not contain a server component, an -# empty string is returned. -# -function docker_server_for_image() { - image_name=$1; shift || fatal "${FUNCNAME} usage error" - IFS='/' read -r -a segments <<< "$image_name" - if [[ "${#segments[@]}" -gt "2" ]]; then - echo "${segments[0]}" - else - echo "" - fi -} - -# -# latest_git_version -# -# latest_git_version returns the highest semantic version -# number found in the repository, with the form "vX.Y.Z". -# Version numbers not matching the semver release format -# are ignored. -# -function latest_git_version() { - git tag -l | egrep "${semver_regex}" | sort -V | tail -1 -} - -# -# is_latest_tag -# -# is_latest_tag returns whether the candidate tag matches -# the latest tag from the git repository, based on semver. -# To be the latest tag, the candidate must match the semver -# release format. -# -function is_latest_tag() { - candidate=$1; shift || fatal "${FUNCNAME} usage error" - if ! [[ "$candidate" =~ $semver_regex ]]; then - return 1 - fi - - latest="$(latest_git_version)" - [[ -z "$latest" || "$candidate" == "$latest" ]] -} - -# -# load_image_if_kind -# -# load_image_if_kind loads an image into all nodes in a kind cluster. -# -function load_image_if_kind() { - local cluster=${KIND_CLUSTER:-kind} - if [[ "$(kubectl config current-context)" == "kind-${cluster}" ]]; then - kind load docker-image --name "${cluster}" "$1" - fi -} diff --git a/hack/tests/e2e-ansible-molecule.sh b/hack/tests/e2e-ansible-molecule.sh index 087db61fc7..736ff55116 100755 --- a/hack/tests/e2e-ansible-molecule.sh +++ b/hack/tests/e2e-ansible-molecule.sh @@ -1,7 +1,17 @@ #!/usr/bin/env bash source hack/lib/common.sh -source hack/lib/image_lib.sh + +# load_image_if_kind +# +# load_image_if_kind loads an image into all nodes in a kind cluster. +# +function load_image_if_kind() { + local cluster=${KIND_CLUSTER:-kind} + if [[ "$(kubectl config current-context)" == "kind-${cluster}" ]]; then + kind load docker-image --name "${cluster}" "$1" + fi +} set -eu diff --git a/images/ansible-operator/Dockerfile b/images/ansible-operator/Dockerfile index 636a91c708..81ae054633 100644 --- a/images/ansible-operator/Dockerfile +++ b/images/ansible-operator/Dockerfile @@ -1,4 +1,24 @@ +# Build the manager binary +FROM --platform=$BUILDPLATFORM golang:1.15 as builder +ARG TARGETARCH + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY . . + +# Build +RUN GOOS=linux GOARCH=$TARGETARCH make build/ansible-operator + +# Final image. FROM registry.access.redhat.com/ubi8/ubi:8.3-227 +ARG TARGETARCH RUN mkdir -p /etc/ansible \ && echo "localhost ansible_connection=local" > /etc/ansible/hosts \ @@ -10,12 +30,10 @@ ENV HOME=/opt/ansible \ USER_NAME=ansible \ USER_UID=1001 -# Install python dependencies -# Ensure fresh metadata rather than cached metadata in the base by running -# yum clean all && rm -rf /var/yum/cache/* first -RUN yum clean all && rm -rf /var/cache/yum/* \ - && yum -y update \ - && yum install -y libffi-devel openssl-devel python38-devel gcc python38-pip python38-setuptools \ +# Install python dependencies after freshening metadata. +RUN dnf clean all && rm -rf /var/cache/dnf/* \ + && dnf update -y \ + && dnf install -y libffi-devel openssl-devel python38-devel gcc python38-pip python38-setuptools \ && pip3 install --no-cache-dir \ cryptography==3.3.2 \ ansible-runner==1.3.4 \ @@ -25,9 +43,8 @@ RUN yum clean all && rm -rf /var/cache/yum/* \ openshift==0.10.3 \ ansible==2.9.15 \ jmespath==0.10.0 \ - && yum remove -y gcc libffi-devel openssl-devel python38-devel \ - && yum clean all \ - && rm -rf /var/cache/yum + && dnf remove -y gcc libffi-devel openssl-devel python38-devel \ + && dnf clean all && rm -rf /var/cache/dnf/* # Ensure directory permissions are properly set RUN echo "${USER_NAME}:x:${USER_UID}:0:${USER_NAME} user:${HOME}:/sbin/nologin" >> /etc/passwd \ @@ -35,14 +52,12 @@ RUN echo "${USER_NAME}:x:${USER_UID}:0:${USER_NAME} user:${HOME}:/sbin/nologin" && chown -R ${USER_UID}:0 ${HOME} \ && chmod -R ug+rwx ${HOME} -RUN TINIARCH=$(case $(arch) in x86_64) echo -n amd64 ;; ppc64le) echo -n ppc64el ;; aarch64) echo -n arm64 ;; *) echo -n $(arch) ;; esac) \ - && curl -L -o /tini https://github.com/krallin/tini/releases/latest/download/tini-$TINIARCH \ +RUN curl -L -o /tini https://github.com/krallin/tini/releases/latest/download/tini-${TARGETARCH} \ && chmod +x /tini WORKDIR ${HOME} USER ${USER_UID} -ARG BIN=bin/ansible-operator -COPY $BIN /usr/local/bin/ansible-operator +COPY --from=builder /workspace/build/ansible-operator /usr/local/bin/ansible-operator ENTRYPOINT ["/tini", "--", "/usr/local/bin/ansible-operator", "run", "--watches-file=./watches.yaml"] diff --git a/images/custom-scorecard-tests/Dockerfile b/images/custom-scorecard-tests/Dockerfile index e5dcabaf95..07f1a411fb 100644 --- a/images/custom-scorecard-tests/Dockerfile +++ b/images/custom-scorecard-tests/Dockerfile @@ -1,3 +1,22 @@ +# Build the custom-scorecard-tests binary +FROM --platform=$BUILDPLATFORM golang:1.15 as builder +ARG TARGETARCH + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY . . + +# Build +RUN GOOS=linux GOARCH=$TARGETARCH make build/custom-scorecard-tests + +# Final image. FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3-230 ENV HOME=/opt/custom-scorecard-tests \ @@ -8,8 +27,7 @@ RUN echo "${USER_NAME}:x:${USER_UID}:0:${USER_NAME} user:${HOME}:/sbin/nologin" WORKDIR ${HOME} -ARG BIN=bin/custom-scorecard-tests -COPY $BIN /usr/local/bin/custom-scorecard-tests +COPY --from=builder /workspace/build/custom-scorecard-tests /usr/local/bin/custom-scorecard-tests ENTRYPOINT ["/usr/local/bin/custom-scorecard-tests"] diff --git a/images/helm-operator/Dockerfile b/images/helm-operator/Dockerfile index 8ad5e30380..7b674974ea 100644 --- a/images/helm-operator/Dockerfile +++ b/images/helm-operator/Dockerfile @@ -1,3 +1,22 @@ +# Build the manager binary +FROM --platform=$BUILDPLATFORM golang:1.15 as builder +ARG TARGETARCH + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY . . + +# Build +RUN GOOS=linux GOARCH=$TARGETARCH make build/helm-operator + +# Final image. FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3-230 ENV HOME=/opt/helm \ @@ -9,7 +28,6 @@ RUN echo "${USER_NAME}:x:${USER_UID}:0:${USER_NAME} user:${HOME}:/sbin/nologin" WORKDIR ${HOME} USER ${USER_UID} -ARG BIN=bin/helm-operator -COPY $BIN /usr/local/bin/helm-operator +COPY --from=builder /workspace/build/helm-operator /usr/local/bin/helm-operator ENTRYPOINT ["/usr/local/bin/helm-operator", "run", "--watches-file=./watches.yaml"] diff --git a/images/operator-sdk/Dockerfile b/images/operator-sdk/Dockerfile index c98e82457d..71dbde5736 100644 --- a/images/operator-sdk/Dockerfile +++ b/images/operator-sdk/Dockerfile @@ -1,8 +1,26 @@ +# Build the operator-sdk binary +FROM --platform=$BUILDPLATFORM golang:1.15 as builder +ARG TARGETARCH + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY . . + +# Build +RUN GOOS=linux GOARCH=$TARGETARCH make build/operator-sdk + +# Final image. FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3-230 RUN microdnf install -y golang make which -ARG BIN=bin/operator-sdk -COPY $BIN /usr/local/bin/operator-sdk +COPY --from=builder /workspace/build/operator-sdk /usr/local/bin/operator-sdk ENTRYPOINT ["/usr/local/bin/operator-sdk"] diff --git a/images/scorecard-test-kuttl/Dockerfile b/images/scorecard-test-kuttl/Dockerfile index acbf232f1a..a382d81114 100644 --- a/images/scorecard-test-kuttl/Dockerfile +++ b/images/scorecard-test-kuttl/Dockerfile @@ -1,4 +1,22 @@ -#FROM docker.io/kudobuilder/kuttl@sha256:c9c5edc27ba6e5e994ffd8cea03368c0d4e274f3c7a00f51c1e360feb573f24e +# Build the scorecard-test-kuttl binary +FROM --platform=$BUILDPLATFORM golang:1.15 as builder +ARG TARGETARCH + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY . . + +# Build +RUN GOOS=linux GOARCH=$TARGETARCH make build/scorecard-test-kuttl + +# Final image. FROM kudobuilder/kuttl:v0.8.0 ENV HOME=/opt/scorecard-test-kuttl \ @@ -10,9 +28,8 @@ RUN echo "${USER_NAME}:x:${USER_UID}:0:${USER_NAME} user:${HOME}:/sbin/nologin" WORKDIR ${HOME} -ARG BIN=bin/scorecard-test-kuttl -COPY $BIN /usr/local/bin/scorecard-test-kuttl -COPY entrypoint /usr/local/bin/entrypoint +COPY --from=builder /workspace/build/scorecard-test-kuttl /usr/local/bin/scorecard-test-kuttl +COPY --from=builder /workspace/images/scorecard-test-kuttl/entrypoint /usr/local/bin/entrypoint ENTRYPOINT ["/usr/local/bin/entrypoint"] diff --git a/images/scorecard-test/Dockerfile b/images/scorecard-test/Dockerfile index cdac469629..996970c5e0 100644 --- a/images/scorecard-test/Dockerfile +++ b/images/scorecard-test/Dockerfile @@ -1,3 +1,22 @@ +# Build the scorecard-test binary +FROM --platform=$BUILDPLATFORM golang:1.15 as builder +ARG TARGETARCH + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY . . + +# Build +RUN GOOS=linux GOARCH=$TARGETARCH make build/scorecard-test + +# Final image. FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3-230 ENV HOME=/opt/scorecard-test \ @@ -8,8 +27,7 @@ RUN echo "${USER_NAME}:x:${USER_UID}:0:${USER_NAME} user:${HOME}:/sbin/nologin" WORKDIR ${HOME} -ARG BIN=bin/scorecard-test -COPY $BIN /usr/local/bin/scorecard-test +COPY --from=builder /workspace/build/scorecard-test /usr/local/bin/scorecard-test ENTRYPOINT ["/usr/local/bin/scorecard-test"] diff --git a/release/Makefile b/release/Makefile index 9d08568480..5c14561004 100644 --- a/release/Makefile +++ b/release/Makefile @@ -6,7 +6,8 @@ SHELL = /bin/bash # Dry run flags. ifneq ($(DRY_RUN),) -SNAPSHOT_FLAGS = --snapshot --skip-publish --rm-dist +SNAPSHOT_FLAGS = --snapshot --skip-publish --skip-sign --rm-dist +$(shell touch changelog/generated/$(GIT_VERSION).md) endif # Ensure that this Makefile is run from the project root (always contains the 'cmd/' directory). @@ -23,6 +24,9 @@ ifeq (,$(GIT_VERSION)) endif $(SCRIPTS_DIR)/fetch goreleaser 0.147.2 GORELEASER_CURRENT_TAG=$(GIT_VERSION) $(TOOLS_DIR)/goreleaser $(SNAPSHOT_FLAGS) --release-notes=changelog/generated/$(GIT_VERSION).md --parallelism 5 +ifneq ($(DRY_RUN),) + rm changelog/generated/$(GIT_VERSION).md +endif ##@ Pre-Release @@ -54,30 +58,6 @@ endif git tag --sign --message "Operator SDK $(RELEASE_VERSION)" $(RELEASE_VERSION) git verify-tag --verbose $(RELEASE_VERSION) -##@ Image deploy - -# Convenience wrappers for pushing all remotely hosted images. -.PHONY: image-push image-push-multiarch -IMAGE_TARGET_LIST = operator-sdk helm-operator ansible-operator scorecard-test scorecard-test-kuttl -image-push: $(foreach i,$(IMAGE_TARGET_LIST),image-push/$(i)) ## Push all images for the host architecture. -image-push-multiarch: $(foreach i,$(IMAGE_TARGET_LIST),image-push-multiarch/$(i)) ## Push the manifest list for all architectures. - -# Push an image for an architecture. -BUILD_IMAGE_REPO = quay.io/operator-framework -IMAGE_REPO ?= $(BUILD_IMAGE_REPO) -GO_ARCH := $(shell go env GOARCH) -image-push/%: IMAGE_PUSH_TAG = $(IMAGE_REPO)/$*-$(GO_ARCH) -image-push/%: - ./hack/image/push-image-tags.sh $(BUILD_IMAGE_REPO)/$*:dev $(IMAGE_PUSH_TAG) - -# Push multiarch images. -ARCHES ?= amd64 arm64 ppc64le s390x -KUTTL_ARCHES := amd64 arm64 ppc64le -image-push-multiarch/scorecard-test-kuttl: ARCHES = $(KUTTL_ARCHES) -image-push-multiarch/%: IMAGE_PUSH_TAG = $(IMAGE_REPO)/$* -image-push-multiarch/%: - ./hack/image/push-manifest-list.sh $(IMAGE_PUSH_TAG) $(ARCHES) - .DEFAULT_GOAL := help .PHONY: help help: ## Show this help screen. diff --git a/test/e2e/ansible/cluster_test.go b/test/e2e/ansible/cluster_test.go index 3cf803b70d..2920a9244a 100644 --- a/test/e2e/ansible/cluster_test.go +++ b/test/e2e/ansible/cluster_test.go @@ -267,7 +267,7 @@ var _ = Describe("Running ansible projects", func() { By("creating a pod with curl image") // todo: the flag --generator=run-pod/v1 is deprecated, however, shows that besides // it should not make any difference and work locally successfully when the flag is removed - // travis has been failing and the curl pod is not found when the flag is not used + // CI has been failing and the curl pod is not found when the flag is not used cmdOpts := []string{ "run", "--generator=run-pod/v1", "curl", "--image=curlimages/curl:7.68.0", "--restart=OnFailure", "--", "curl", "-v", "-k", "-H", fmt.Sprintf(`Authorization: Bearer %s`, token), diff --git a/test/e2e/helm/cluster_test.go b/test/e2e/helm/cluster_test.go index fe966e10fa..4524dce6cc 100644 --- a/test/e2e/helm/cluster_test.go +++ b/test/e2e/helm/cluster_test.go @@ -224,7 +224,7 @@ var _ = Describe("Running Helm projects", func() { By("creating a pod with curl image") // todo: the flag --generator=run-pod/v1 is deprecated, however, shows that besides // it should not make any difference and work locally successfully when the flag is removed - // travis has been failing and the curl pod is not found when the flag is not used + // CI has been failing and the curl pod is not found when the flag is not used cmdOpts := []string{ "run", "--generator=run-pod/v1", "curl", "--image=curlimages/curl:7.68.0", "--restart=OnFailure", "--", "curl", "-v", "-k", "-H", fmt.Sprintf(`Authorization: Bearer %s`, token), diff --git a/website/content/en/docs/contribution-guidelines/developer-guide.md b/website/content/en/docs/contribution-guidelines/developer-guide.md index fa07d2d4ee..0b27498bdd 100644 --- a/website/content/en/docs/contribution-guidelines/developer-guide.md +++ b/website/content/en/docs/contribution-guidelines/developer-guide.md @@ -33,27 +33,20 @@ See the [release guide][dev-release] for more information. ## Continuous Integration (CI) -The operator-sdk repo uses [Travis CI][travis] to test each pull request and build images for both master commits -and releases. You can alter these processes by modifying this [`.travis.yml`][travis.yml] config file. - -### Testing builds with new architectures - -Follow these steps to execute the Travis `Deploy` stage against your branch -to demonstrate that the merge build will complete as expected. - -- Enable Travis in your fork repository. See [this guide][travis-setup] for more information. -- Create public image repos for each image built by `make image-build`; make sure the registry used supports -multi-arch images, like quay.io. - - For each image type, you need one repo for the manifest list and one for each architecture being tested. -- Set each image variable (that ends in `_IMAGE`, not `_BASE_IMAGE`) found in the Makefile -as an environment variable in `.travis.yml`, ex. `export SCORECARD_TEST_IMAGE=//scorecard-test:latest` -- Create a PR with your configuration changes to _your_ fork, with the first commit message containing -`[travis deploy]`. - - This commit is only for testing on your fork's PR. This commit/message should not be present in an operator-sdk - repo PR. -- Ensure the image builds for that PR pass. -- Create a PR to the operator-sdk repo with a description containing a link to the Travis build page -showing a successful deployment stage with your changes. +The operator-sdk repo uses [Github Actions][sdk-actions] to test each pull request and build images for both master commits +and release tags. You can alter these processes by modifying the appropriate [Action config][sdk-action-cfgs]. + +### Adding new architectures + +The operator-sdk project builds binaries for [several os's/architectures][readme-platforms]. +If you wish to add support for a new one, please create a feature request issue before +implementing support for that platform and submitting a PR. + + +If you'd like to implement support yourself, you can test a new architecture by enabling Actions +in your repository, add a platform pair to the `deploy` Action's `build and push` step, +and push to your main branch. Once the updated Action passes, submit a PR linking the passing Action run. + [git-tool]:https://git-scm.com/downloads [go-tool]:https://golang.org/dl/ @@ -62,6 +55,6 @@ showing a successful deployment stage with your changes. [dev-testing]: /docs/contribution-guidelines/testing [dev-docs]: /docs/contribution-guidelines/documentation [dev-release]: /docs/contribution-guidelines/releasing -[travis]: https://docs.travis-ci.com/ -[travis.yml]: https://github.com/operator-framework/operator-sdk/blob/master/.travis.yml -[travis-setup]: https://docs.travis-ci.com/user/tutorial/#to-get-started-with-travis-ci-using-github +[sdk-actions]:https://github.com/operator-framework/operator-sdk/actions +[sdk-action-cfgs]:https://github.com/operator-framework/operator-sdk/tree/master/.github/workflows +[readme-platforms]:https://github.com/operator-framework/operator-sdk/tree/master/README.md#platforms