diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 00000000..4e1f2eea --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,238 @@ +# ============= +# This file is automatically generated from the templates in stackabletech/operator-templating +# DON'T MANUALLY EDIT THIS FILE +# ============= +--- +name: Build hbase-operator Artifacts + +permissions: {} + +on: + push: + branches: + - main + tags: + - '[0-9][0-9].[0-9]+.[0-9]+-rc[0-9]+' + - '[0-9][0-9].[0-9]+.[0-9]+' + schedule: + # 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' + +env: + OPERATOR_NAME: "hbase-operator" + RUST_NIGHTLY_TOOLCHAIN_VERSION: "nightly-2025-10-23" + NIX_PKG_MANAGER_VERSION: "2.30.0" + RUST_TOOLCHAIN_VERSION: "1.89.0" + HADOLINT_VERSION: "v2.14.0" + PYTHON_VERSION: "3.14" + CARGO_TERM_COLOR: always + +jobs: + cargo-udeps: + name: Run cargo-udeps + runs-on: ubuntu-latest + env: + RUSTC_BOOTSTRAP: 1 + steps: + - name: Install host dependencies + uses: awalsh128/cache-apt-pkgs-action@2c09a5e66da6c8016428a2172bd76e5e4f14bb17 # v1.5.3 + with: + packages: protobuf-compiler krb5-user libkrb5-dev libclang-dev liblzma-dev libssl-dev pkg-config apt-transport-https + version: ubuntu-latest + + - name: Checkout Repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + submodules: recursive + + - name: Install Rust ${{ env.RUST_TOOLCHAIN_VERSION }} toolchain + uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b + with: + toolchain: ${{ env.RUST_TOOLCHAIN_VERSION }} + + - name: Setup Rust Cache + uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + with: + cache-all-crates: "true" + key: udeps + + - name: Install cargo-udeps + uses: stackabletech/cargo-install-action@8f7dbbcd2ebe22717efc132d0dd61e80841994b9 # cargo-udeps + + - name: Run cargo-udeps + run: cargo udeps --workspace --all-targets + + build-container-image: + name: Build/Publish ${{ matrix.runner.arch }} Image + needs: + - cargo-udeps + permissions: + id-token: write + strategy: + fail-fast: false + matrix: + runner: + - { name: "ubuntu-latest", arch: "amd64" } + - { name: "ubicloud-standard-8-arm", arch: "arm64" } + runs-on: ${{ matrix.runner.name }} + outputs: + operator-version: ${{ steps.version.outputs.OPERATOR_VERSION }} + steps: + - name: Install host dependencies + uses: awalsh128/cache-apt-pkgs-action@2c09a5e66da6c8016428a2172bd76e5e4f14bb17 # v1.5.3 + with: + packages: protobuf-compiler krb5-user libkrb5-dev libclang-dev liblzma-dev libssl-dev pkg-config apt-transport-https + version: ${{ matrix.runner.name }} + + - name: Checkout Repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + submodules: recursive + + - name: Update/Extract Operator Version + id: version + if: github.event_name == 'pull_request' + env: + PR_BASE_REF: ${{ github.event.pull_request.base.ref }} + PR_NUMBER: ${{ github.event.pull_request.number }} + GITHUB_DEBUG: ${{ runner.debug }} + shell: bash + run: | + set -euo pipefail + [ -n "$GITHUB_DEBUG" ] && set -x + CURRENT_VERSION=$(cargo metadata --format-version 1 --no-deps | jq -r '.packages[0].version') + if [ "$PR_BASE_REF" == 'main' ]; then + NEW_VERSION="0.0.0-pr$PR_NUMBER" + else + NEW_VERSION="$CURRENT_VERSION-pr$PR_NUMBER" + fi + sed -i "s/version = \"${CURRENT_VERSION}\"/version = \"${NEW_VERSION}\"/" Cargo.toml + echo "OPERATOR_VERSION=$NEW_VERSION" | tee -a "$GITHUB_OUTPUT" + - name: Install Nix + uses: cachix/install-nix-action@fc6e360bedc9ee72d75e701397f0bb30dce77568 # v31.5.2 + + - name: Install Rust ${{ env.RUST_TOOLCHAIN_VERSION }} Toolchain + uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b + with: + toolchain: ${{ env.RUST_TOOLCHAIN_VERSION }} + + - name: Build Container Image + id: build + uses: stackabletech/actions/build-container-image@29bea1b451c0c2e994bd495969286f95bf49ed6a # v0.11.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 + with: + image-registry-uri: oci.stackable.tech + image-registry-username: robot$sdp+github-action-build + image-registry-password: ${{ secrets.HARBOR_ROBOT_SDP_GITHUB_ACTION_BUILD_SECRET }} + image-repository: sdp/${{ env.OPERATOR_NAME }} + image-manifest-tag: ${{ steps.build.outputs.image-manifest-tag }} + source-image-uri: ${{ steps.build.outputs.image-manifest-uri }} + + publish-index-manifest: + name: Publish/Sign ${{ needs.build-container-image.outputs.operator-version }} Index + needs: + - build-container-image + permissions: + id-token: write + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Publish and Sign Image Index + uses: stackabletech/actions/publish-image-index-manifest@29bea1b451c0c2e994bd495969286f95bf49ed6a # v0.11.0 + with: + image-registry-uri: oci.stackable.tech + image-registry-username: robot$sdp+github-action-build + image-registry-password: ${{ secrets.HARBOR_ROBOT_SDP_GITHUB_ACTION_BUILD_SECRET }} + image-repository: sdp/${{ env.OPERATOR_NAME }} + image-index-manifest-tag: ${{ needs.build-container-image.outputs.operator-version }} + + publish-helm-chart: + name: Package/Publish ${{ needs.build-container-image.outputs.operator-version }} Helm Chart + needs: + - build-container-image + permissions: + id-token: write + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + submodules: recursive + + - name: Package, Publish, and Sign Helm Chart + uses: stackabletech/actions/publish-helm-chart@29bea1b451c0c2e994bd495969286f95bf49ed6a # v0.11.0 + with: + chart-registry-uri: oci.stackable.tech + chart-registry-username: robot$sdp-charts+github-action-build + chart-registry-password: ${{ secrets.HARBOR_ROBOT_SDP_CHARTS_GITHUB_ACTION_BUILD_SECRET }} + chart-repository: sdp-charts + chart-directory: deploy/helm/${{ env.OPERATOR_NAME }} + chart-version: ${{ needs.build-container-image.outputs.operator-version }} + app-version: ${{ needs.build-container-image.outputs.operator-version }} + + openshift-preflight-check: + name: Run OpenShift Preflight Check for ${{ needs.build-container-image.outputs.operator-version }}-${{ matrix.arch }} + needs: + - build-container-image + - publish-index-manifest + strategy: + fail-fast: false + matrix: + arch: + - amd64 + - arm64 + runs-on: ubuntu-latest + steps: + - name: Run OpenShift Preflight Check + uses: stackabletech/actions/run-openshift-preflight@29bea1b451c0c2e994bd495969286f95bf49ed6a # v0.11.0 + with: + image-index-uri: oci.stackable.tech/sdp/${{ env.OPERATOR_NAME }}:${{ needs.build-container-image.outputs.operator-version }} + image-architecture: ${{ matrix.arch }} + + notify: + name: Failure Notification + needs: + - build-container-image + - publish-index-manifest + - publish-helm-chart + runs-on: ubuntu-latest + if: failure() || github.run_attempt > 1 + steps: + - name: Checkout Repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Send Notification + uses: stackabletech/actions/send-slack-notification@29bea1b451c0c2e994bd495969286f95bf49ed6a # v0.11.0 + with: + publish-helm-chart-result: ${{ needs.publish-helm-chart.result }} + publish-manifests-result: ${{ needs.publish-index-manifest.result }} + build-result: ${{ needs.build-container-image.result }} + slack-token: ${{ secrets.SLACK_CONTAINER_IMAGE_TOKEN }} + channel-id: C07UG6JH44F # notifications-container-images + type: container-image-build diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index ceea33b8..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,273 +0,0 @@ -# ============= -# This file is automatically generated from the templates in stackabletech/operator-templating -# DON'T MANUALLY EDIT THIS FILE -# ============= ---- -name: Stackable Build Pipeline - -on: - push: - branches: - - main - - staging - - trying - - "renovate/**" - tags: - - '[0-9][0-9].[0-9]+.[0-9]+' - - '[0-9][0-9].[0-9]+.[0-9]+-rc[0-9]+' - pull_request: - merge_group: - schedule: - # Run every Saturday morning: https://crontab.guru/#15_3_*_*_6 - - cron: '15 3 * * 6' - workflow_dispatch: - -env: - CARGO_TERM_COLOR: always - CARGO_INCREMENTAL: '0' - CARGO_PROFILE_DEV_DEBUG: '0' - RUST_TOOLCHAIN_VERSION: "1.89.0" - RUST_NIGHTLY_TOOLCHAIN_VERSION: "nightly-2025-10-23" - PYTHON_VERSION: "3.14" - RUSTFLAGS: "-D warnings" - RUSTDOCFLAGS: "-D warnings" - RUST_LOG: "info" - -jobs: - # Identify unused dependencies - run_udeps: - name: Run Cargo Udeps - runs-on: ubuntu-latest - env: - RUSTC_BOOTSTRAP: 1 - steps: - - name: Install host dependencies - uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # v1.6.0 - with: - packages: protobuf-compiler krb5-user libkrb5-dev libclang-dev liblzma-dev libssl-dev pkg-config apt-transport-https - version: ubuntu-latest - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - persist-credentials: false - submodules: recursive - - uses: dtolnay/rust-toolchain@6d653acede28d24f02e3cd41383119e8b1b35921 - with: - toolchain: ${{ env.RUST_TOOLCHAIN_VERSION }} - - uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # v2.8.1 - with: - key: udeps - cache-all-crates: "true" - - uses: stackabletech/cargo-install-action@cargo-udeps - - run: cargo udeps --workspace --all-targets - - # This job evaluates the github environment to determine why this action is running and decides if - # Helm charts are published based on this. - # - # The following scenarios are identified: - # - all pull requests land are published: - # condition: github.event_name == "pull_request" - # - # - all tagged releases are published: - # condition: github.event_name == 'push' & github.ref.startswith('refs/tags/') - # - # - all pushes to main (i.e. PR-merges) and all scheduled/manual workflow runs on main land are published: - # condition: ( github.event_name == 'push' | github.event_name == 'schedule' | github.event_name == 'workflow_dispatch' ) & github.ref == 'refs/heads/main' - # - # Any other scenarios (e.g. when a branch is created/pushed) will cause the publish step to be skipped, most commonly this is expected to happen for the - # branches that the GitHub merge queue feature uses internally for which the checks need to run, but we do not want artifacts to be published. - check_helm_publish: - name: Decide if Helm charts are pushed to the helm repository based on action trigger - runs-on: ubuntu-latest - outputs: - skip_helm: ${{ steps.checkhelmpublish.outputs.skip_helm }} - steps: - - id: checkhelmpublish - env: - TRIGGER: ${{ github.event_name }} - GITHUB_REF: ${{ github.ref }} - run: | - if [[ "$TRIGGER" == "pull_request" ]]; then - echo "skip_helm=false" >> "$GITHUB_OUTPUT" - elif [[ ( "$TRIGGER" == "push" || "$TRIGGER" == "schedule" || "$TRIGGER" == "workflow_dispatch" ) && "$GITHUB_REF" == "refs/heads/main" ]]; then - echo "skip_helm=false" >> "$GITHUB_OUTPUT" - elif [[ "$TRIGGER" == "push" && $GITHUB_REF == refs/tags/* ]]; then - echo "skip_helm=false" >> "$GITHUB_OUTPUT" - else - echo "Unknown trigger and ref combination encountered, skipping publish step: $TRIGGER $GITHUB_REF" - echo "skip_helm=true" >> "$GITHUB_OUTPUT" - fi - - # TODO (@Techassi): Most of these publishing and signing tasks can be done by our own actions. - # Make use of them just like we do in docker-images. - package_and_publish: - name: Package Charts, Build Docker Image and publish them - ${{ matrix.runner }} - needs: - - run_udeps - - check_helm_publish - strategy: - matrix: - runner: ["ubuntu-latest", "ubicloud-standard-8-arm"] - runs-on: ${{ matrix.runner }} - timeout-minutes: 120 - permissions: - id-token: write - env: - OCI_REGISTRY_SDP_PASSWORD: ${{ secrets.HARBOR_ROBOT_SDP_GITHUB_ACTION_BUILD_SECRET }} - OCI_REGISTRY_SDP_USERNAME: "robot$sdp+github-action-build" - OCI_REGISTRY_SDP_CHARTS_PASSWORD: ${{ secrets.HARBOR_ROBOT_SDP_CHARTS_GITHUB_ACTION_BUILD_SECRET }} - OCI_REGISTRY_SDP_CHARTS_USERNAME: "robot$sdp-charts+github-action-build" - if: needs.check_helm_publish.outputs.skip_helm != 'true' - outputs: - IMAGE_TAG: ${{ steps.printtag.outputs.IMAGE_TAG }} - steps: - - name: Install host dependencies - uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # v1.6.0 - with: - packages: protobuf-compiler krb5-user libkrb5-dev libclang-dev liblzma-dev libssl-dev pkg-config apt-transport-https - version: ${{ matrix.runner }} - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - persist-credentials: false - submodules: recursive - - uses: cachix/install-nix-action@fd24c48048070c1be9acd18c9d369a83f0fe94d7 # v31.8.1 - - uses: dtolnay/rust-toolchain@6d653acede28d24f02e3cd41383119e8b1b35921 - with: - toolchain: ${{ env.RUST_TOOLCHAIN_VERSION }} - components: rustfmt - # This step checks if the current run was triggered by a push to a pr (or a pr being created). - # If this is the case it changes the version of this project in all Cargo.toml files to include the suffix - # "-pr" so that the published artifacts can be linked to this PR. - - uses: stackabletech/cargo-install-action@main - with: - crate: cargo-edit - bin: cargo-set-version - - name: Update version if PR against main branch - if: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main' }} - env: - PR_NUMBER: ${{ github.event.pull_request.number }} - run: | - PR_VERSION="0.0.0-pr${PR_NUMBER}" - cargo set-version --offline --workspace "$PR_VERSION" - - name: Update version if PR against non-main branch - # For PRs to be merged against a release branch, use the version that has already been set in the calling script. - # We can't rely on cargo set-version here as we will break semver rules when changing the version to make it - # specific to this PR e.g. 1.2.0 --> 1.2.0-pr678, so set it manually. - if: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref != 'main' }} - env: - PR_NUMBER: ${{ github.event.pull_request.number }} - shell: bash - run: | - set -euo pipefail - - MANIFEST_VERSION=$(cargo metadata --format-version 1 --no-deps | jq -r '.packages[0].version') - PR_VERSION="${MANIFEST_VERSION}-pr${PR_NUMBER}" - sed -i "s/version = \"${MANIFEST_VERSION}\"/version = \"${PR_VERSION}\"/" Cargo.toml - - # Recreate charts and publish charts and docker image. - - name: Install cosign - uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 - - name: Install syft - uses: anchore/sbom-action/download-syft@8e94d75ddd33f69f691467e42275782e4bfefe84 # v0.20.9 - - name: Build Docker image and Helm chart - run: | - # Installing helm and yq on ubicloud-standard-8-arm only - if [ "$(arch)" = "aarch64" ]; then - curl -fsSL https://packages.buildkite.com/helm-linux/helm-debian/gpgkey | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://packages.buildkite.com/helm-linux/helm-debian/any/ any main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list - sudo apt-get -y update - sudo apt-get -y install helm - sudo wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 -O /usr/bin/yq && sudo chmod +x /usr/bin/yq - fi - - make build - - name: Publish Docker image and Helm chart - if: ${{ !github.event.pull_request.head.repo.fork }} - run: | - # We want to publish helmcharts only once as they have a common name, while still publishing both images with architecture specific tags - if [ "$(uname -m)" = "x86_64" ]; then - make publish - else - make docker-publish - fi - # Output the name of the published image to the Job output for later use - - id: printtag - name: Output image name and tag - if: ${{ !github.event.pull_request.head.repo.fork }} - run: echo "IMAGE_TAG=$(make print-docker-tag)" >> "$GITHUB_OUTPUT" - - create_manifest_list: - name: Build and publish manifest list - if: ${{ !github.event.pull_request.head.repo.fork }} - needs: - - package_and_publish - runs-on: ubuntu-latest - permissions: - id-token: write - env: - OCI_REGISTRY_SDP_PASSWORD: ${{ secrets.HARBOR_ROBOT_SDP_GITHUB_ACTION_BUILD_SECRET }} - OCI_REGISTRY_SDP_USERNAME: "robot$sdp+github-action-build" - OCI_REGISTRY_SDP_CHARTS_PASSWORD: ${{ secrets.HARBOR_ROBOT_SDP_CHARTS_GITHUB_ACTION_BUILD_SECRET }} - OCI_REGISTRY_SDP_CHARTS_USERNAME: "robot$sdp-charts+github-action-build" - steps: - - name: Install cosign - uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 - - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - persist-credentials: false - submodules: recursive - # This step checks if the current run was triggered by a push to a pr (or a pr being created). - # If this is the case it changes the version of this project in all Cargo.toml files to include the suffix - # "-pr" so that the published artifacts can be linked to this PR. - - uses: stackabletech/cargo-install-action@main - with: - crate: cargo-edit - bin: cargo-set-version - - name: Update version if PR against main branch - if: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main' }} - env: - PR_NUMBER: ${{ github.event.pull_request.number }} - run: | - PR_VERSION="0.0.0-pr${PR_NUMBER}" - cargo set-version --offline --workspace "$PR_VERSION" - - name: Update version if PR against non-main branch - # For PRs to be merged against a release branch, use the version that has already been set in the calling script. - # We can't rely on cargo set-version here as we will break semver rules when changing the version to make it - # specific to this PR e.g. 1.2.0 --> 1.2.0-pr678, so set it manually. - if: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref != 'main' }} - env: - PR_NUMBER: ${{ github.event.pull_request.number }} - shell: bash - run: | - set -euo pipefail - - MANIFEST_VERSION=$(cargo metadata --format-version 1 --no-deps | jq -r '.packages[0].version') - PR_VERSION="${MANIFEST_VERSION}-pr${PR_NUMBER}" - sed -i "s/version = \"${MANIFEST_VERSION}\"/version = \"${PR_VERSION}\"/" Cargo.toml - - name: Build manifest list - run: | - # Creating manifest list - make -e docker-manifest-list-build - # Pushing and signing manifest list - make -e docker-manifest-list-publish - - openshift_preflight: - name: Run the OpenShift Preflight check on the published images - if: ${{ !github.event.pull_request.head.repo.fork }} - needs: - - create_manifest_list - - package_and_publish - runs-on: ubuntu-latest - env: - IMAGE_TAG: ${{ needs.package_and_publish.outputs.IMAGE_TAG }} - steps: - - name: Install preflight - run: | - wget https://github.com/redhat-openshift-ecosystem/openshift-preflight/releases/download/1.10.0/preflight-linux-amd64 - chmod +x preflight-linux-amd64 - - name: Check container - run: | - ARCH_FOR_PREFLIGHT="$(arch | sed -e 's#x86_64#amd64#' | sed -e 's#aarch64#arm64#')" - ./preflight-linux-amd64 check container "$IMAGE_TAG" --platform "${ARCH_FOR_PREFLIGHT}" > preflight.out - - name: "Passed?" - run: '[ "$(jq -r .passed < preflight.out)" == true ]' diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index b49b7712..0f9f268e 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -41,7 +41,7 @@ jobs: # TODO: Enable the scheduled runs which hard-code what profile to use - name: Run Integration Test id: test - uses: stackabletech/actions/run-integration-test@75e0756966dea229d697165bfd06ba79abcda72c # v0.10.3 + uses: stackabletech/actions/run-integration-test@29bea1b451c0c2e994bd495969286f95bf49ed6a # v0.11.0 with: replicated-api-token: ${{ secrets.REPLICATED_API_TOKEN }} test-mode-input: ${{ inputs.test-mode-input }} @@ -51,7 +51,7 @@ jobs: - name: Send Notification if: ${{ failure() || github.run_attempt > 1 }} - uses: stackabletech/actions/send-slack-notification@75e0756966dea229d697165bfd06ba79abcda72c # v0.10.3 + uses: stackabletech/actions/send-slack-notification@29bea1b451c0c2e994bd495969286f95bf49ed6a # v0.11.0 with: slack-token: ${{ secrets.SLACK_INTEGRATION_TEST_TOKEN }} failed-tests: ${{ steps.test.outputs.failed-tests }} diff --git a/.github/workflows/pr_pre-commit.yaml b/.github/workflows/pr_pre-commit.yaml index 0d46fc8a..acbc963e 100644 --- a/.github/workflows/pr_pre-commit.yaml +++ b/.github/workflows/pr_pre-commit.yaml @@ -11,6 +11,7 @@ env: RUST_TOOLCHAIN_VERSION: "nightly-2025-10-23" HADOLINT_VERSION: "v2.14.0" PYTHON_VERSION: "3.14" + JINJA2_CLI_VERSION: "0.8.2" jobs: pre-commit: @@ -26,10 +27,11 @@ jobs: persist-credentials: false submodules: recursive fetch-depth: 0 - - uses: stackabletech/actions/run-pre-commit@75e0756966dea229d697165bfd06ba79abcda72c # v0.10.3 + - uses: stackabletech/actions/run-pre-commit@29bea1b451c0c2e994bd495969286f95bf49ed6a # v0.11.0 with: python-version: ${{ env.PYTHON_VERSION }} rust: ${{ env.RUST_TOOLCHAIN_VERSION }} hadolint: ${{ env.HADOLINT_VERSION }} nix: ${{ env.NIX_PKG_MANAGER_VERSION }} nix-github-token: ${{ secrets.GITHUB_TOKEN }} + jinja2-cli: ${{ env.JINJA2_CLI_VERSION }} diff --git a/.yamllint.yaml b/.yamllint.yaml index 08bf167f..020cb5f0 100644 --- a/.yamllint.yaml +++ b/.yamllint.yaml @@ -13,3 +13,6 @@ rules: indentation: indent-sequences: consistent comments-indentation: disable # This is generally useless and interferes with commented example values + braces: + max-spaces-inside: 1 + max-spaces-inside-empty: 0 diff --git a/Makefile b/Makefile index d88faf7d..ed4bae07 100644 --- a/Makefile +++ b/Makefile @@ -9,17 +9,11 @@ .PHONY: build publish -TAG := $(shell git rev-parse --short HEAD) OPERATOR_NAME := hbase-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 @@ -33,73 +27,6 @@ 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 cyclonedx-json@1.5=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 @@ -133,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) diff --git a/docker/Dockerfile b/docker/Dockerfile index 241c5714..b3502ee0 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -21,6 +21,8 @@ FROM oci.stackable.tech/sdp/ubi9-rust-builder:latest AS builder FROM registry.access.redhat.com/ubi9/ubi-minimal:latest AS operator ARG VERSION +# NOTE (@Techassi): This is required for OpenShift/Red Hat certification +# Keeping this as "1" seems to be fine since a couple of years /shrug ARG RELEASE="1" # These are chosen at random and are this high on purpose to have very little chance to clash with an existing user or group on the host system diff --git a/renovate.json b/renovate.json index f28373c7..2e0c6125 100644 --- a/renovate.json +++ b/renovate.json @@ -3,5 +3,5 @@ "extends": [ "local>stackabletech/.github:renovate-config" ], - "ignorePaths": [".github/workflows/build.yml", ".github/workflows/general_daily_security.yml", ".github/workflows/integration-test.yml", ".github/workflows/pr_pre-commit.yaml"] + "ignorePaths": [".github/workflows/build.yaml", ".github/workflows/build.yml", ".github/workflows/general_daily_security.yml", ".github/workflows/integration-test.yml", ".github/workflows/pr_pre-commit.yaml"] }