Skip to content

Commit

Permalink
Add Release Workflow (#111)
Browse files Browse the repository at this point in the history
Each build will get one or more image tags, depending on whether it's a build
of the master branch, a PR branch, or a release branch.  Computation of the
image tags is handled by the metadata-action workflow.

* Add git-version-gen script to compute a VERSION value from the git repo.
* Remove the .version file; this is now computed by the git-version-gen script.

* Add rules to Makefile to generate the .version file and use its value.
* Use "v" prefix in release tag filter.
* Add workflow to verify that tags are annotated.
* Use metadata-action to generate all of the appropriate tags for the build
* Use build-push-action to execute all of the tags for the build.

Tagging:
* Builds of the master branch get an image tag of "master".
* Builds of a PR branch get an image tag similar to "pr-3".
* Builds of a PR or merge event get an image tag similar to "0.0.1.12-9e04", which is the value generated by git-version-gen.
* Builds of a PR or merge event will get an image tag that is the long SHA of the top commit, which is the image tag expected by nnf-deploy.
* Builds of a push to a tag will get an image tag that matches the git tag.
* Builds of a push to a tag will get an image tag of "latest".

Signed-off-by: Dean Roehrich <[email protected]>
  • Loading branch information
roehrich-hpe authored Dec 19, 2022
1 parent 0f5951d commit 409e4fc
Show file tree
Hide file tree
Showing 6 changed files with 323 additions and 66 deletions.
104 changes: 58 additions & 46 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ name: Docker build and push

on:
push:
branches:
- 'master'
- 'releases/v*'
tags:
- 'v*'
pull_request:
branches: [ master ]
workflow_dispatch:
branches:
- 'master'
- 'releases/v*'

env:
# TEST_TARGET: Name of the testing target in the Dockerfile
Expand All @@ -21,68 +27,74 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: "Checkout repository"
id: checkout_repo
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}

- name: Lowercase repository name for docker build
- name: "Lowercase repository name for docker build"
id: lowercase-repository-name
run: |
echo "HPE_BUILD_REPO=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
echo "HPE_DEPLOY_REPO=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
- name: set TAG & TESTTAG for main/master
if: ${{ github.event.repository.default_branch == 'main' || github.event.repository.default_branch == 'master' }}
run: |
echo "TAG=${{ github.sha }}" >> ${GITHUB_ENV}
echo "LATESTTAG=latest" >> ${GITHUB_ENV}
echo "TESTTAG=test-${{ github.sha }}" >> ${GITHUB_ENV}
run: echo "REPO_NAME=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV

- name: set TAG & TESTTAG for all other branches
if: ${{ github.event.repository.default_branch != 'main' && github.event.repository.default_branch != 'master' }}
- name: "Set tags for main/master"
id: set_tags
run: |
echo "TAG=dev-${{ github.sha }}" >> ${GITHUB_ENV}
echo "LATESTTAG=dev-latest" >> ${GITHUB_ENV}
echo "TESTTAG=test-${{ github.sha }}" >> ${GITHUB_ENV}
- name: Docker login
echo "VERSION_TAG=$(./git-version-gen | grep -v UNKNOWN)" >> ${GITHUB_ENV}
echo "TEST_TAG=$(git rev-parse HEAD)-test" >> ${GITHUB_ENV}
echo "SHA_TAG=$(git rev-parse HEAD)" >> ${GITHUB_ENV}
echo "${GITHUB_ENV}:"
cat ${GITHUB_ENV}
shell: bash

- name: "Docker metadata"
id: meta
uses: docker/metadata-action@v4
with:
images: |
ghcr.io/${{ env.REPO_NAME }}
tags: |
# For merge to master branch, tag example: 'master'
type=ref,event=branch
# For PR event, tag example: 'pr-3'
type=ref,event=pr
# For PR event or merge event, tag example: 1.0.1.12-5667
type=raw,value=${{ env.VERSION_TAG }}
# For PR event or merge, tag example: 566769e04d2436cf5f42ae4f46092c7dff6e668e
type=raw,value=${{ env.SHA_TAG }}
# For push to semver tag, tag example: 1.0.2
# This also sets 'latest'.
type=semver,pattern={{version}}
# For push to semver tag, tag example: 1.0
type=semver,pattern={{major}}.{{minor}}
- name: "Docker login"
id: docker_login
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build the test Docker image
if: ${{ env.DO_TEST == 'true' }}
- name: "Build the test Docker image"
id: docker_build_test_target
if: ${{ env.DO_TEST == 'true' }}
uses: docker/build-push-action@v2
with:
push: false
target: ${{ env.TEST_TARGET }}
tags: ${{ env.HPE_BUILD_REPO }}:${{ env.TESTTAG }}
tags: ${{ env.REPO_NAME }}:${{ env.TEST_TAG }}

- name: Run the Docker image unit tests
- name: "Run the Docker image unit tests"
id: docker_test
if: ${{ env.DO_TEST == 'true' }}
run: docker run ${HPE_BUILD_REPO}:${TESTTAG}
run: docker run ${{ env.REPO_NAME }}:${{ env.TEST_TAG }}

- name: Build the final Docker image
- name: "Build the final Docker image"
id: docker_build
uses: docker/build-push-action@v2
uses: docker/build-push-action@v3
with:
push: false
tags: ${{ env.HPE_BUILD_REPO }}:${{ env.TAG }}

- name: Peek at the docker images
run: docker images

- name: Tag the build
run: docker tag docker.io/${HPE_BUILD_REPO}:${TAG} ghcr.io/${HPE_DEPLOY_REPO}:${TAG}

- name: Tag the build as latest
run: docker tag ${HPE_BUILD_REPO}:${TAG} ghcr.io/${HPE_DEPLOY_REPO}:${LATESTTAG}

- name: Push the tagged build
if: ${{ env.DO_PUSH == 'true' }}
run: docker push ghcr.io/${HPE_DEPLOY_REPO}:${TAG}
push: true
tags: ${{ steps.meta.outputs.tags }}

- name: Push the build tagged as latest
if: ${{ env.DO_PUSH == 'true' }}
run: docker push ghcr.io/${HPE_DEPLOY_REPO}:${LATESTTAG}
26 changes: 26 additions & 0 deletions .github/workflows/verify_tag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Pushing a tag triggers this workflow, which verifies that it is an
# annotated tag.
name: Verify tag

on:
push:
tags:
- "v*"

env:
IMAGE_NAME: ${{ github.repository }}

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# actions/checkout@v3 breaks annotated tags by converting them into
# lightweight tags, so we need to force fetch the tag again
# See: https://github.com/actions/checkout/issues/290
- name: "Repair tag"
run: git fetch -f origin ${{ github.ref }}:${{ github.ref }}
- name: "Verify tag is annotated"
run: if test x$(git for-each-ref ${{ github.ref }} | awk '{print $2}') = xtag; then /bin/true; else echo "\"${{ github.ref }}\" does not look like an annotated tag!"; /bin/false; fi
- name: "Echo release tag"
run: echo "TAG=${{ github.repository }}:${{ github.ref }}"
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ commands.log
kind-config.yaml
standalone-playground
nnf-sos
.version

# .vscode log files
.vscode/*.log
.vscode/*.log
1 change: 0 additions & 1 deletion .version

This file was deleted.

51 changes: 33 additions & 18 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ DOCKER ?= docker
# To re-generate a bundle for another specific version without changing the standard setup, you can:
# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2)
# - use environment variables to overwrite this value (e.g export VERSION=0.0.2)
VERSION ?= $(shell sed 1q .version)
# NOTE: git-version-gen will generate a value for VERSION, unless you override it.

# CHANNELS define the bundle channels used in the bundle.
# Add a new line here if you would like to change its default config. (E.g CHANNELS = "preview,fast,stable")
Expand Down Expand Up @@ -58,10 +58,6 @@ IMAGE_TAG_BASE ?= ghcr.io/nearnodeflash/nnf-sos

# BUNDLE_IMG defines the image:tag used for the bundle.
# You can use it as an arg. (E.g make bundle-build BUNDLE_IMG=<some-registry>/<project-name-bundle>:<tag>)
BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:v$(VERSION)

# Image URL to use all building/pushing image targets
IMG ?= $(IMAGE_TAG_BASE):$(VERSION)

# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.25.0
Expand Down Expand Up @@ -204,7 +200,8 @@ vet: ## Run go vet against code.
# If set, default reporter print out all specs as they begin.
#

container-unit-test: ## Build docker image with the manager and execute unit tests.
container-unit-test: VERSION ?= $(shell cat .version)
container-unit-test: .version ## Build docker image with the manager and execute unit tests.
${DOCKER} build -f Dockerfile --label $(IMAGE_TAG_BASE)-$@:$(VERSION)-$@ -t $(IMAGE_TAG_BASE)-$@:$(VERSION) --target testing .
${DOCKER} run --rm -t --name $@-nnf-sos $(IMAGE_TAG_BASE)-$@:$(VERSION)

Expand Down Expand Up @@ -237,14 +234,17 @@ build: generate fmt vet ## Build manager binary.
run: manifests generate fmt vet ## Run a controller from your host.
go run ./main.go

docker-build: ## Build docker image with the manager.
time ${DOCKER} build --build-arg FAILFAST -t ${IMG} .
docker-build: VERSION ?= $(shell cat .version)
docker-build: .version ## Build docker image with the manager.
time ${DOCKER} build --build-arg FAILFAST -t $(IMAGE_TAG_BASE):$(VERSION) .

docker-push: ## Push docker image with the manager.
${DOCKER} push ${IMG}
docker-push: VERSION ?= $(shell cat .version)
docker-push: .version ## Push docker image with the manager.
${DOCKER} push $(IMAGE_TAG_BASE):$(VERSION)

kind-push: ## Push docker image to kind
kind load docker-image --nodes `kubectl get node --no-headers -o custom-columns=":metadata.name" | paste -d, -s -` ${IMG}
kind-push: VERSION ?= $(shell cat .version)
kind-push: .version ## Push docker image to kind
kind load docker-image --nodes `kubectl get node --no-headers -o custom-columns=":metadata.name" | paste -d, -s -` $(IMAGE_TAG_BASE):$(VERSION)
${DOCKER} pull gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0
kind load docker-image --nodes `kubectl get node -l cray.nnf.manager=true --no-headers -o custom-columns=":metadata.name" | paste -d, -s -` gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0

Expand All @@ -256,11 +256,22 @@ install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~
uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/crd | kubectl delete -f -

deploy: kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
./deploy.sh deploy $(KUSTOMIZE) $(IMG) $(OVERLAY)
deploy: VERSION ?= $(shell cat .version)
deploy: .version kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
./deploy.sh deploy $(KUSTOMIZE) $(IMAGE_TAG_BASE):$(VERSION) $(OVERLAY)

undeploy: VERSION ?= $(shell cat .version)
undeploy: .version kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config.
./deploy.sh undeploy $(KUSTOMIZE) $(IMAGE_TAG_BASE):$(VERSION) $(OVERLAY)

# Let .version be phony so that a git update to the workarea can be reflected
# in it each time it's needed.
.PHONY: .version
.version: ## Uses the git-version-gen script to generate a tag version
./git-version-gen --fallback `git rev-parse HEAD` > .version

undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config.
./deploy.sh undeploy $(KUSTOMIZE) $(IMG) $(OVERLAY)
clean:
rm -f .version

## Location to install dependencies to
LOCALBIN ?= $(shell pwd)/bin
Expand Down Expand Up @@ -300,11 +311,15 @@ bundle: manifests kustomize ## Generate bundle manifests and metadata, then vali
operator-sdk bundle validate ./bundle

.PHONY: bundle-build
bundle-build: ## Build the bundle image.
bundle-build: VERSION ?= $(shell cat .version)
bundle-build: BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:v$(VERSION)
bundle-build: .version ## Build the bundle image.
${DOCKER} build -f bundle.Dockerfile -t $(BUNDLE_IMG) .

.PHONY: bundle-push
bundle-push: ## Push the bundle image.
bundle-push: VERSION ?= $(shell cat .version)
bundle-push: BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:v$(VERSION)
bundle-push: .version ## Push the bundle image.
$(MAKE) docker-push IMG=$(BUNDLE_IMG)

.PHONY: opm
Expand Down
Loading

0 comments on commit 409e4fc

Please sign in to comment.