Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 50 additions & 20 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,7 @@ on:
# Run every Saturday morning: https://crontab.guru/#15_3_*_*_6
- cron: '15 3 * * 6'
pull_request:
paths:
- '.github/workflows/build.yaml'
- 'rust-toolchain.toml'
- '.dockerignore'
- 'deploy/**'
- '.cargo/**'
- 'docker/**'
- 'Cargo.*'
- '*.rs'
# Do not limit by paths. This workflow contains a required job.
merge_group:

env:
Expand All @@ -39,8 +31,41 @@ env:
CARGO_TERM_COLOR: always

jobs:
# This workflow contains a "required job", and GitHub Actions isn't clever
# enough to detect that it should be skipped, and therefore pass (like they
# allow for skipping jobs in a workflow).
# Therefore, we have to move path filters/globs down to an actual job, and
# emit an output that can be used to skip irrelevant jobs.
detect-changes:
name: Detect relevant changed files
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: stackabletech/actions/detect-changes@babe44d7b1db87f8e7731c011151d22a8a374191 # v0.12.0
with:
persist-credentials: false
fetch-depth: 0

- name: Check for changed files
id: check
uses: ./.github/actions/detect-changes
with:
patterns: |
- '.github/workflows/build.yaml'
- 'rust-toolchain.toml'
- '.dockerignore'
- 'deploy/**'
- '.cargo/**'
- 'docker/**'
- 'Cargo.*'
- '*.rs'
outputs:
detected: ${{ steps.check.outputs.detected }}

cargo-udeps:
name: Run cargo-udeps
if: needs.detect-changes.outputs.detected == 'true'
needs: [detect-changes]
runs-on: ubuntu-latest
env:
RUSTC_BOOTSTRAP: 1
Expand Down Expand Up @@ -76,7 +101,8 @@ jobs:

build-container-image:
name: Build/Publish ${{ matrix.runner.arch }} Image
if: github.event_name != 'merge_group'
if: (github.event_name != 'merge_group') && needs.detect-changes.outputs.detected == 'true'
needs: [detect-changes]
permissions:
id-token: write
strategy:
Expand Down Expand Up @@ -140,15 +166,15 @@ jobs:

- name: Build Container Image
id: build
uses: stackabletech/actions/build-container-image@29bea1b451c0c2e994bd495969286f95bf49ed6a # v0.11.0
uses: stackabletech/actions/build-container-image@babe44d7b1db87f8e7731c011151d22a8a374191 # v0.12.0
with:
image-name: ${{ env.OPERATOR_NAME }}
image-index-manifest-tag: ${{ steps.version.outputs.OPERATOR_VERSION }}
build-arguments: VERSION=${{ steps.version.outputs.OPERATOR_VERSION }}
container-file: docker/Dockerfile

- name: Publish Container Image
uses: stackabletech/actions/publish-image@29bea1b451c0c2e994bd495969286f95bf49ed6a # v0.11.0
uses: stackabletech/actions/publish-image@babe44d7b1db87f8e7731c011151d22a8a374191 # v0.12.0
with:
image-registry-uri: oci.stackable.tech
image-registry-username: robot$sdp+github-action-build
Expand All @@ -159,8 +185,9 @@ jobs:

publish-index-manifest:
name: Publish/Sign ${{ needs.build-container-image.outputs.operator-version }} Index
if: github.event_name != 'merge_group'
if: (github.event_name != 'merge_group') && needs.detect-changes.outputs.detected == 'true'
needs:
- detect-changes
- build-container-image
permissions:
id-token: write
Expand All @@ -172,7 +199,7 @@ jobs:
persist-credentials: false

- name: Publish and Sign Image Index
uses: stackabletech/actions/publish-image-index-manifest@29bea1b451c0c2e994bd495969286f95bf49ed6a # v0.11.0
uses: stackabletech/actions/publish-image-index-manifest@babe44d7b1db87f8e7731c011151d22a8a374191 # v0.12.0
with:
image-registry-uri: oci.stackable.tech
image-registry-username: robot$sdp+github-action-build
Expand All @@ -182,8 +209,9 @@ jobs:

publish-helm-chart:
name: Package/Publish ${{ needs.build-container-image.outputs.operator-version }} Helm Chart
if: github.event_name != 'merge_group'
if: (github.event_name != 'merge_group') && needs.detect-changes.outputs.detected == 'true'
needs:
- detect-changes
- build-container-image
permissions:
id-token: write
Expand All @@ -196,7 +224,7 @@ jobs:
submodules: recursive

- name: Package, Publish, and Sign Helm Chart
uses: stackabletech/actions/publish-helm-chart@29bea1b451c0c2e994bd495969286f95bf49ed6a # v0.11.0
uses: stackabletech/actions/publish-helm-chart@babe44d7b1db87f8e7731c011151d22a8a374191 # v0.12.0
with:
chart-registry-uri: oci.stackable.tech
chart-registry-username: robot$sdp-charts+github-action-build
Expand All @@ -208,8 +236,9 @@ jobs:

openshift-preflight-check:
name: Run OpenShift Preflight Check for ${{ needs.build-container-image.outputs.operator-version }}-${{ matrix.arch }}
if: github.event_name != 'merge_group'
if: (github.event_name != 'merge_group') && needs.detect-changes.outputs.detected == 'true'
needs:
- detect-changes
- build-container-image
- publish-index-manifest
strategy:
Expand All @@ -221,7 +250,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Run OpenShift Preflight Check
uses: stackabletech/actions/run-openshift-preflight@29bea1b451c0c2e994bd495969286f95bf49ed6a # v0.11.0
uses: stackabletech/actions/run-openshift-preflight@babe44d7b1db87f8e7731c011151d22a8a374191 # v0.12.0
with:
image-index-uri: oci.stackable.tech/sdp/${{ env.OPERATOR_NAME }}:${{ needs.build-container-image.outputs.operator-version }}
image-architecture: ${{ matrix.arch }}
Expand All @@ -243,8 +272,9 @@ jobs:

notify:
name: Failure Notification
if: (failure() || github.run_attempt > 1) && github.event_name != 'merge_group'
if: (failure() || github.run_attempt > 1) && github.event_name != 'merge_group' && needs.detect-changes.outputs.detected == 'true'
needs:
- detect-changes
- build-container-image
- publish-index-manifest
- publish-helm-chart
Expand All @@ -256,7 +286,7 @@ jobs:
persist-credentials: false

- name: Send Notification
uses: stackabletech/actions/send-slack-notification@29bea1b451c0c2e994bd495969286f95bf49ed6a # v0.11.0
uses: stackabletech/actions/send-slack-notification@babe44d7b1db87f8e7731c011151d22a8a374191 # v0.12.0
with:
publish-helm-chart-result: ${{ needs.publish-helm-chart.result }}
publish-manifests-result: ${{ needs.publish-index-manifest.result }}
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ result
image.tar

tilt_options.json
local_values.yaml

.direnv/
.direnvrc
Expand Down
89 changes: 4 additions & 85 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,11 @@

.PHONY: build publish

TAG := $(shell git rev-parse --short HEAD)
OPERATOR_NAME := secret-operator
VERSION := $(shell cargo metadata --format-version 1 | jq -r '.packages[] | select(.name=="stackable-${OPERATOR_NAME}") | .version')
ARCH := $(shell uname -m | sed -e 's#x86_64#amd64#' | sed -e 's#aarch64#arm64#')

OCI_REGISTRY_HOSTNAME := oci.stackable.tech
OCI_REGISTRY_PROJECT_IMAGES := sdp
OCI_REGISTRY_PROJECT_CHARTS := sdp-charts
# This will be overwritten by an environmental variable if called from the github action
HELM_CHART_NAME := ${OPERATOR_NAME}
HELM_CHART_ARTIFACT := target/helm/${OPERATOR_NAME}-${VERSION}.tgz

SHELL=/usr/bin/env bash -euo pipefail

Expand All @@ -33,78 +27,12 @@ render-docs:
docker-build:
docker build --force-rm --build-arg VERSION=${VERSION} -t "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}-${ARCH}" -f docker/Dockerfile .

docker-publish:
# Push to Harbor
# We need to use "value" here to prevent the variable from being recursively expanded by make (username contains a dollar sign, since it's a Harbor bot)
docker login --username '${value OCI_REGISTRY_SDP_USERNAME}' --password '${OCI_REGISTRY_SDP_PASSWORD}' '${OCI_REGISTRY_HOSTNAME}'
DOCKER_OUTPUT=$$(docker push --all-tags '${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}');\
# Obtain the digest of the pushed image from the output of `docker push`, because signing by tag is deprecated and will be removed from cosign in the future\
REPO_DIGEST_OF_IMAGE=$$(echo "$$DOCKER_OUTPUT" | awk '/^${VERSION}-${ARCH}: digest: sha256:[0-9a-f]{64} size: [0-9]+$$/ { print $$3 }');\
if [ -z "$$REPO_DIGEST_OF_IMAGE" ]; then\
echo 'Could not find repo digest for container image: ${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}-${ARCH}';\
exit 1;\
fi;\
# This generates a signature and publishes it to the registry, next to the image\
# Uses the keyless signing flow with Github Actions as identity provider\
cosign sign -y "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}@$$REPO_DIGEST_OF_IMAGE";\
# Generate the SBOM for the operator image, this leverages the already generated SBOM for the operator binary by cargo-cyclonedx\
syft scan --output [email protected]=sbom.json --select-catalogers "-cargo-auditable-binary-cataloger,+sbom-cataloger" --scope all-layers --source-name "${OPERATOR_NAME}" --source-version "${VERSION}-${ARCH}" "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}@$$REPO_DIGEST_OF_IMAGE";\
# Determine the PURL for the container image\
URLENCODED_REPO_DIGEST_OF_IMAGE=$$(echo "$$REPO_DIGEST_OF_IMAGE" | sed 's/:/%3A/g');\
PURL="pkg:oci/${OPERATOR_NAME}@$$URLENCODED_REPO_DIGEST_OF_IMAGE?arch=${ARCH}&repository_url=${OCI_REGISTRY_HOSTNAME}%2F${OCI_REGISTRY_PROJECT_IMAGES}%2F${OPERATOR_NAME}";\
# Get metadata from the image\
IMAGE_DESCRIPTION=$$(docker inspect --format='{{.Config.Labels.description}}' "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}-${ARCH}");\
IMAGE_NAME=$$(docker inspect --format='{{.Config.Labels.name}}' "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}-${ARCH}");\
# Merge the SBOM with the metadata for the operator\
jq -s '{"metadata":{"component":{"description":"'"$$IMAGE_NAME. $$IMAGE_DESCRIPTION"'","supplier":{"name":"Stackable GmbH","url":["https://stackable.tech/"]},"author":"Stackable GmbH","purl":"'"$$PURL"'","publisher":"Stackable GmbH"}}} * .[0]' sbom.json > sbom.merged.json;\
# Attest the SBOM to the image\
cosign attest -y --predicate sbom.merged.json --type cyclonedx "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}@$$REPO_DIGEST_OF_IMAGE"

# This assumes "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}-amd64 and "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}-arm64 are built and pushed
docker-manifest-list-build:
docker manifest create "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}" --amend "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}-amd64" --amend "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}-arm64"

docker-manifest-list-publish:
# Push to Harbor
# We need to use "value" here to prevent the variable from being recursively expanded by make (username contains a dollar sign, since it's a Harbor bot)
docker login --username '${value OCI_REGISTRY_SDP_USERNAME}' --password '${OCI_REGISTRY_SDP_PASSWORD}' '${OCI_REGISTRY_HOSTNAME}'
DIGEST_HARBOR=$$(docker manifest push "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}");\
# Refer to image via its digest (oci.stackable.tech/sdp/airflow@sha256:0a1b2c...);\
# This generates a signature and publishes it to the registry, next to the image\
# Uses the keyless signing flow with Github Actions as identity provider\
cosign sign -y "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}@$$DIGEST_HARBOR"

# TODO remove if not used/needed
docker: docker-build docker-publish

print-docker-tag:
@echo "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}"

helm-publish:
# Push to Harbor
# We need to use "value" here to prevent the variable from being recursively expanded by make (username contains a dollar sign, since it's a Harbor bot)
helm registry login --username '${value OCI_REGISTRY_SDP_CHARTS_USERNAME}' --password '${OCI_REGISTRY_SDP_CHARTS_PASSWORD}' '${OCI_REGISTRY_HOSTNAME}'
# Obtain the digest of the pushed artifact from the output of `helm push`, because signing by tag is deprecated and will be removed from cosign in the future\
HELM_OUTPUT=$$(helm push '${HELM_CHART_ARTIFACT}' 'oci://${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_CHARTS}' 2>&1);\
REPO_DIGEST_OF_ARTIFACT=$$(echo "$$HELM_OUTPUT" | awk '/^Digest: sha256:[0-9a-f]{64}$$/ { print $$2 }');\
if [ -z "$$REPO_DIGEST_OF_ARTIFACT" ]; then\
echo 'Could not find repo digest for helm chart: ${HELM_CHART_NAME}';\
exit 1;\
fi;\
# Login to Harbor, needed for cosign to be able to push the signature for the Helm chart\
docker login --username '${value OCI_REGISTRY_SDP_CHARTS_USERNAME}' --password '${OCI_REGISTRY_SDP_CHARTS_PASSWORD}' '${OCI_REGISTRY_HOSTNAME}';\
# This generates a signature and publishes it to the registry, next to the chart artifact\
# Uses the keyless signing flow with Github Actions as identity provider\
cosign sign -y "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_CHARTS}/${HELM_CHART_NAME}@$$REPO_DIGEST_OF_ARTIFACT"

helm-package:
mkdir -p target/helm && helm package --destination target/helm deploy/helm/${OPERATOR_NAME}

## Chart related targets
compile-chart: version crds config

chart-clean:
rm -rf "deploy/helm/${OPERATOR_NAME}/configs"
rm -rf "deploy/helm/${OPERATOR_NAME}/crds"

version:
cat "deploy/helm/${OPERATOR_NAME}/Chart.yaml" | yq ".version = \"${VERSION}\" | .appVersion = \"${VERSION}\"" > "deploy/helm/${OPERATOR_NAME}/Chart.yaml.new"
Expand All @@ -116,11 +44,9 @@ config:
cp -r deploy/config-spec/* "deploy/helm/${OPERATOR_NAME}/configs";\
fi

# We generate a crds.yaml, so that the effect of code changes are visible.
# The operator will take care of the CRD rollout itself.
crds:
mkdir -p extra
cargo run --bin stackable-"${OPERATOR_NAME}" -- crd > extra/crds.yaml
mkdir -p deploy/helm/"${OPERATOR_NAME}"/crds
cargo run --bin stackable-"${OPERATOR_NAME}" -- crd | yq eval '.metadata.annotations["helm.sh/resource-policy"]="keep"' - > "deploy/helm/${OPERATOR_NAME}/crds/crds.yaml"

chart-lint: compile-chart
docker run -it -v $(shell pwd):/build/helm-charts -w /build/helm-charts quay.io/helmpack/chart-testing:v3.5.0 ct lint --config deploy/helm/ct.yaml
Expand All @@ -134,14 +60,7 @@ regenerate-charts: chart-clean compile-chart
regenerate-nix:
nix run --extra-experimental-features "nix-command flakes" -f . regenerateNixLockfiles

build: regenerate-charts regenerate-nix helm-package docker-build

# This target is used by the CI
# It doesn't make use of any nix dependencies and thus aviods building the
# operator unnecessarily often.
build-ci: regenerate-charts helm-package docker-build

publish: docker-publish helm-publish
build: regenerate-charts regenerate-nix docker-build

check-nix:
@which nix || (echo "Error: 'nix' is not installed. Please install it to proceed."; exit 1)
Expand Down
29 changes: 20 additions & 9 deletions Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ custom_build(
outputs_image_ref_to='result/ref',
)

# Load the latest CRDs from Nix
watch_file('result')
if os.path.exists('result'):
k8s_yaml('result/crds.yaml')

# We need to set the correct image annotation on the operator Deployment to use e.g.
# oci.stackable.tech/sandbox/opa-operator:7y19m3d8clwxlv34v5q2x4p7v536s00g instead of
# oci.stackable.tech/sandbox/opa-operator:0.0.0-dev (which does not exist)
Expand All @@ -30,12 +35,18 @@ helm_values = settings.get('helm_values', None)

helm_override_image_repository = 'image.repository=' + registry + '/' + operator_name

k8s_yaml(helm(
'deploy/helm/' + operator_name,
name=operator_name,
namespace="stackable-operators",
set=[
helm_override_image_repository,
],
values=helm_values,
))
# Exclude stale CRDs from Helm chart, and apply the rest
helm_crds, helm_non_crds = filter_yaml(
helm(
'deploy/helm/' + operator_name,
name=operator_name,
namespace="stackable-operators",
set=[
helm_override_image_repository,
],
values=helm_values,
),
api_version = "^apiextensions\\.k8s\\.io/.*$",
kind = "^CustomResourceDefinition$",
)
k8s_yaml(helm_non_crds)
Loading
Loading