From b362d403ed1c72448bae79ebd844bdeb10af6018 Mon Sep 17 00:00:00 2001 From: Joel Takvorian Date: Tue, 3 Mar 2026 16:57:47 +0100 Subject: [PATCH 1/2] GH workflows: Remove trigger on pull_request_target Replaced with pull_request + workflow_run Although the risk of pwn request attacks was mitigated with the ok-to-test label protection, this was still human-error prone. This workflow increases security by not running any code with secret access privileges. --- .github/workflows/build_image_pr.yml | 40 +++++++++++++ .github/workflows/push_image_pr.yml | 84 +++++++++++++--------------- Makefile | 28 ++++++++-- 3 files changed, 102 insertions(+), 50 deletions(-) create mode 100644 .github/workflows/build_image_pr.yml diff --git a/.github/workflows/build_image_pr.yml b/.github/workflows/build_image_pr.yml new file mode 100644 index 000000000..8b2dfafbc --- /dev/null +++ b/.github/workflows/build_image_pr.yml @@ -0,0 +1,40 @@ +name: Build PR image and upload artifact +on: + pull_request: + types: [labeled] + +env: + WF_REGISTRY: quay.io/netobserv + WF_IMAGE: network-observability-operator + WF_ORG: netobserv + WF_RELIMG_VERSION: main + +jobs: + build-pr-image: + if: ${{ github.event.label.name == 'ok-to-test' }} + name: Build PR image and upload artifact + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install make + run: sudo apt -y install make + - name: get short sha + run: echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + - name: build and save operator image + run: OCI_BUILD_OPTS="--label quay.expires-after=2w" IMAGE=${{ env.WF_REGISTRY }}/${{ env.WF_IMAGE }}:${{ env.short_sha }} CLEAN_BUILD=1 make tar-image + - name: get related images target + if: startsWith(github.ref_name, 'release-') + run: echo "WF_RELIMG_VERSION=${{ github.ref_name }}" >> $GITHUB_ENV + - name: build and save bundle image + run: OCI_BUILD_OPTS="--label quay.expires-after=2w" IMAGE_ORG=${{ env.WF_ORG }} VERSION=${{ env.short_sha }} PLG_VERSION=${{ env.WF_RELIMG_VERSION }} FLP_VERSION=${{ env.WF_RELIMG_VERSION }} BPF_VERSION=${{ env.WF_RELIMG_VERSION }} BUNDLE_VERSION=0.0.0-sha-${{ env.short_sha }} CLEAN_BUILD=1 BUNDLE_SET_DATE=true make bundle bundle-tar + - name: build catalog + run: IMAGE_ORG=${{ env.WF_ORG }} BUNDLE_VERSION=0.0.0-sha-${{ env.short_sha }} make catalog-tar + - name: save PR number + run: | + echo ${{ github.event.number }} > ./out/pr-id + echo ${{ env.short_sha }} > ./out/short-sha + - name: upload artifacts + uses: actions/upload-artifact@v4 + with: + name: pr + path: out/ diff --git a/.github/workflows/push_image_pr.yml b/.github/workflows/push_image_pr.yml index ab4a65eca..f024fcfe7 100644 --- a/.github/workflows/push_image_pr.yml +++ b/.github/workflows/push_image_pr.yml @@ -1,79 +1,73 @@ -name: Build and push PR image to quay.io +name: Push PR image to quay.io on: - pull_request_target: - types: [labeled] + workflow_run: + workflows: ["Build PR image and upload artifact"] + types: + - completed env: WF_REGISTRY_USER: netobserv+github_ci - WF_REGISTRY: quay.io/netobserv - WF_IMAGE: network-observability-operator - WF_ORG: netobserv - WF_RELIMG_VERSION: main jobs: push-pr-image: - if: ${{ github.event.label.name == 'ok-to-test' }} + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' name: push PR image runs-on: ubuntu-latest steps: - - name: install make - run: sudo apt-get install make - - name: set up go 1.x - uses: actions/setup-go@v3 + - name: download artifact + uses: actions/download-artifact@v5 with: - go-version: '1.25' - - name: checkout - uses: actions/checkout@v3 - with: - ref: "refs/pull/${{ github.event.number }}/merge" + name: pr + run-id: ${{github.event.workflow_run.id }} + github-token: ${{secrets.GITHUB_TOKEN}} + - name: load images + run: | + docker load --input ./operator.tar + docker load --input ./bundle.tar + docker load --input ./catalog.tar - name: docker login to quay.io uses: docker/login-action@v2 with: username: ${{ env.WF_REGISTRY_USER }} password: ${{ secrets.QUAY_SECRET }} registry: quay.io - - name: get short sha - run: echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - - name: build image - run: OCI_BUILD_OPTS="--label quay.expires-after=2w" IMAGE_ORG=${{ env.WF_ORG }} IMAGE=${{ env.WF_REGISTRY }}/${{ env.WF_IMAGE }}:${{ env.short_sha }} CLEAN_BUILD=1 make image-build - - name: push image - run: IMAGE_ORG=${{ env.WF_ORG }} IMAGE=${{ env.WF_REGISTRY }}/${{ env.WF_IMAGE }}:${{ env.short_sha }} make image-push - - name: build and push manifest - run: IMAGE_ORG=${{ env.WF_ORG }} IMAGE=${{ env.WF_REGISTRY }}/${{ env.WF_IMAGE }}:${{ env.short_sha }} make manifest-build manifest-push - - name: get related images target - if: startsWith(github.ref_name, 'release-') + - name: push images run: | - echo "WF_RELIMG_VERSION=${{ github.ref_name }}" >> $GITHUB_ENV - - name: build bundle - run: OCI_BUILD_OPTS="--label quay.expires-after=2w" IMAGE_ORG=${{ env.WF_ORG }} VERSION=${{ env.short_sha }} PLG_VERSION=${{ env.WF_RELIMG_VERSION }} FLP_VERSION=${{ env.WF_RELIMG_VERSION }} BPF_VERSION=${{ env.WF_RELIMG_VERSION }} BUNDLE_VERSION=0.0.0-sha-${{ env.short_sha }} CLEAN_BUILD=1 BUNDLE_SET_DATE=true make bundle bundle-build - - name: push bundle to quay.io - run: IMAGE_ORG=${{ env.WF_ORG }} VERSION=${{ env.short_sha }} BUNDLE_VERSION=0.0.0-sha-${{ env.short_sha }} make bundle-push - - name: build catalog - run: IMAGE_ORG=${{ env.WF_ORG }} BUNDLE_VERSION=0.0.0-sha-${{ env.short_sha }} make shortlived-catalog-build - - name: push catalog to quay.io - run: IMAGE_ORG=${{ env.WF_ORG }} BUNDLE_VERSION=0.0.0-sha-${{ env.short_sha }} make catalog-push - - uses: actions/github-script@v5 + DOCKER_BUILDKIT=1 docker push $(cat ./operator-name) + DOCKER_BUILDKIT=1 docker push $(cat ./bundle-name) + DOCKER_BUILDKIT=1 docker push $(cat ./catalog-name) + - uses: actions/github-script@v6 with: github-token: ${{secrets.GITHUB_TOKEN}} script: | + var fs = require('fs'); + var issueNumber = Number(fs.readFileSync('./pr-id')); + var shortSha = String(fs.readFileSync('./short-sha')).trim(); + var operatorImage = fs.readFileSync('./operator-name'); + var bundleImage = fs.readFileSync('./bundle-name'); + var catalogImage = fs.readFileSync('./catalog-name'); github.rest.issues.createComment({ - issue_number: context.issue.number, + issue_number: issueNumber, owner: context.repo.owner, repo: context.repo.repo, body: `New images: - * ${{ env.WF_REGISTRY }}/${{ env.WF_IMAGE }}:${{ env.short_sha }} - * ${{ env.WF_REGISTRY }}/${{ env.WF_IMAGE }}-bundle:v0.0.0-sha-${{ env.short_sha }} - * ${{ env.WF_REGISTRY }}/${{ env.WF_IMAGE }}-catalog:v0.0.0-sha-${{ env.short_sha }} + \`\`\`bash + ${operatorImage} + ${bundleImage} + ${catalogImage} + \`\`\` - They will expire after two weeks. + They will expire in two weeks. To deploy this build: \`\`\`bash # Direct deployment, from operator repo - IMAGE=${{ env.WF_REGISTRY }}/${{ env.WF_IMAGE }}:${{ env.short_sha }} make deploy + IMAGE=${operatorImage} make deploy # Or using operator-sdk - operator-sdk run bundle ${{ env.WF_REGISTRY }}/${{ env.WF_IMAGE }}-bundle:v0.0.0-sha-${{ env.short_sha }} + operator-sdk run bundle ${bundleImage} \`\`\` Or as a Catalog Source: @@ -85,7 +79,7 @@ jobs: namespace: openshift-marketplace spec: sourceType: grpc - image: ${{ env.WF_REGISTRY }}/${{ env.WF_IMAGE }}-catalog:v0.0.0-sha-${{ env.short_sha }} + image: ${catalogImage} displayName: NetObserv development catalog publisher: Me updateStrategy: diff --git a/Makefile b/Makefile index 9a247574f..80990c6f8 100644 --- a/Makefile +++ b/Makefile @@ -374,6 +374,14 @@ extract-binaries: ## Extract all MULTIARCH_TARGETS binaries mkdir -p release-assets; \ $(foreach target,$(MULTIARCH_TARGETS),$(call extract_target,$(target))) +.PHONY: tar-image +tar-image: MULTIARCH_TARGETS=amd64 +tar-image: image-build ## Build single arch (amd64) and save as a tar + $(OCI_BIN) tag $(IMAGE)-amd64 $(IMAGE) + mkdir -p ./out + $(OCI_BIN) save -o out/operator.tar $(IMAGE) + echo $(IMAGE) > ./out/operator-name + ##@ Deployment install: kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. @@ -451,7 +459,13 @@ bundle-build: ## Build the bundle image. .PHONY: bundle-push bundle-push: ## Push the bundle image. - $(OCI_BIN) push ${BUNDLE_IMAGE}; + $(OCI_BIN) push ${BUNDLE_IMAGE} + +.PHONY: bundle-tar +bundle-tar: bundle-build ## Build bundle image and save as a tar + mkdir -p ./out + $(OCI_BIN) save -o out/bundle.tar $(BUNDLE_IMAGE) + echo $(BUNDLE_IMAGE) > ./out/bundle-name # A comma-separated list of bundle images (e.g. make catalog-build BUNDLE_IMAGES=example.com/operator-bundle:v0.1.0,example.com/operator-bundle:v0.2.0). # These images MUST exist in a registry and be pull-able. @@ -473,10 +487,6 @@ catalog-build: opm ## Build a catalog image. OPM=$(OPM) BUNDLE_IMAGE=$(BUNDLE_IMAGE) BUNDLE_TAG="v$(BUNDLE_VERSION)" ./hack/update_fbc.sh $(OCI_BIN) build $(OCI_BUILD_OPTS) --build-arg CATALOG_PATH="catalog/out/v$(BUNDLE_VERSION)" -f catalog.Dockerfile -t $(CATALOG_IMAGE) . -shortlived-catalog-build: ## Build a temporary catalog image, expiring after 2 weeks on quay - $(MAKE) catalog-build CATALOG_IMAGE=temp-catalog - echo "FROM temp-catalog" | $(OCI_BIN) build --label quay.expires-after=2w -t $(CATALOG_IMAGE) - - # Push the catalog image. .PHONY: catalog-push catalog-push: ## Push a catalog image. @@ -492,6 +502,14 @@ catalog-deploy: ## Deploy a catalog image. catalog-undeploy: ## Undeploy a catalog image. kubectl delete -f ./config/samples/catalog/catalog.yaml +.PHONY: catalog-tar +catalog-tar: ## Build catalog image and save as a tar, expiring after 2 weeks on quay + $(MAKE) catalog-build CATALOG_IMAGE=temp-catalog + echo "FROM temp-catalog" | $(OCI_BIN) build --label quay.expires-after=2w -t $(CATALOG_IMAGE) - + mkdir -p ./out + $(OCI_BIN) save -o out/catalog.tar $(CATALOG_IMAGE) + echo $(CATALOG_IMAGE) > ./out/catalog-name + ##@ Misc .PHONY: test-workflow From 3ad813bf2d34d53c2fcbba482caa453855c3637d Mon Sep 17 00:00:00 2001 From: Joel Takvorian Date: Tue, 3 Mar 2026 17:13:12 +0100 Subject: [PATCH 2/2] build catalog after operator/bundle are pushed --- .github/workflows/build_image_pr.yml | 2 -- .github/workflows/push_image_pr.yml | 12 ++++++------ Makefile | 14 +++++--------- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build_image_pr.yml b/.github/workflows/build_image_pr.yml index 8b2dfafbc..c1e124585 100644 --- a/.github/workflows/build_image_pr.yml +++ b/.github/workflows/build_image_pr.yml @@ -27,8 +27,6 @@ jobs: run: echo "WF_RELIMG_VERSION=${{ github.ref_name }}" >> $GITHUB_ENV - name: build and save bundle image run: OCI_BUILD_OPTS="--label quay.expires-after=2w" IMAGE_ORG=${{ env.WF_ORG }} VERSION=${{ env.short_sha }} PLG_VERSION=${{ env.WF_RELIMG_VERSION }} FLP_VERSION=${{ env.WF_RELIMG_VERSION }} BPF_VERSION=${{ env.WF_RELIMG_VERSION }} BUNDLE_VERSION=0.0.0-sha-${{ env.short_sha }} CLEAN_BUILD=1 BUNDLE_SET_DATE=true make bundle bundle-tar - - name: build catalog - run: IMAGE_ORG=${{ env.WF_ORG }} BUNDLE_VERSION=0.0.0-sha-${{ env.short_sha }} make catalog-tar - name: save PR number run: | echo ${{ github.event.number }} > ./out/pr-id diff --git a/.github/workflows/push_image_pr.yml b/.github/workflows/push_image_pr.yml index f024fcfe7..d6ee3ea52 100644 --- a/.github/workflows/push_image_pr.yml +++ b/.github/workflows/push_image_pr.yml @@ -26,18 +26,19 @@ jobs: run: | docker load --input ./operator.tar docker load --input ./bundle.tar - docker load --input ./catalog.tar - name: docker login to quay.io uses: docker/login-action@v2 with: username: ${{ env.WF_REGISTRY_USER }} password: ${{ secrets.QUAY_SECRET }} registry: quay.io - - name: push images + - name: push operator and bundle run: | DOCKER_BUILDKIT=1 docker push $(cat ./operator-name) DOCKER_BUILDKIT=1 docker push $(cat ./bundle-name) - DOCKER_BUILDKIT=1 docker push $(cat ./catalog-name) + - name: build and push catalog + run: | + IMAGE_ORG=${{ env.WF_ORG }} BUNDLE_VERSION=0.0.0-sha-$(cat ./short-sha) make shortlived-catalog-build catalog-push - uses: actions/github-script@v6 with: github-token: ${{secrets.GITHUB_TOKEN}} @@ -47,7 +48,6 @@ jobs: var shortSha = String(fs.readFileSync('./short-sha')).trim(); var operatorImage = fs.readFileSync('./operator-name'); var bundleImage = fs.readFileSync('./bundle-name'); - var catalogImage = fs.readFileSync('./catalog-name'); github.rest.issues.createComment({ issue_number: issueNumber, owner: context.repo.owner, @@ -56,7 +56,7 @@ jobs: \`\`\`bash ${operatorImage} ${bundleImage} - ${catalogImage} + quay.io/netobserv/network-observability-operator-catalog:v0.0.0-sha-${shortSha} \`\`\` They will expire in two weeks. @@ -79,7 +79,7 @@ jobs: namespace: openshift-marketplace spec: sourceType: grpc - image: ${catalogImage} + image: quay.io/netobserv/network-observability-operator-catalog:v0.0.0-sha-${shortSha} displayName: NetObserv development catalog publisher: Me updateStrategy: diff --git a/Makefile b/Makefile index 80990c6f8..d7809aef1 100644 --- a/Makefile +++ b/Makefile @@ -487,10 +487,14 @@ catalog-build: opm ## Build a catalog image. OPM=$(OPM) BUNDLE_IMAGE=$(BUNDLE_IMAGE) BUNDLE_TAG="v$(BUNDLE_VERSION)" ./hack/update_fbc.sh $(OCI_BIN) build $(OCI_BUILD_OPTS) --build-arg CATALOG_PATH="catalog/out/v$(BUNDLE_VERSION)" -f catalog.Dockerfile -t $(CATALOG_IMAGE) . +shortlived-catalog-build: ## Build a temporary catalog image, expiring after 2 weeks on quay + $(MAKE) catalog-build CATALOG_IMAGE=temp-catalog + echo "FROM temp-catalog" | $(OCI_BIN) build --label quay.expires-after=2w -t $(CATALOG_IMAGE) - + # Push the catalog image. .PHONY: catalog-push catalog-push: ## Push a catalog image. - $(OCI_BIN) push ${CATALOG_IMAGE}; + $(OCI_BIN) push ${CATALOG_IMAGE} # Deploy the catalog. .PHONY: catalog-deploy @@ -502,14 +506,6 @@ catalog-deploy: ## Deploy a catalog image. catalog-undeploy: ## Undeploy a catalog image. kubectl delete -f ./config/samples/catalog/catalog.yaml -.PHONY: catalog-tar -catalog-tar: ## Build catalog image and save as a tar, expiring after 2 weeks on quay - $(MAKE) catalog-build CATALOG_IMAGE=temp-catalog - echo "FROM temp-catalog" | $(OCI_BIN) build --label quay.expires-after=2w -t $(CATALOG_IMAGE) - - mkdir -p ./out - $(OCI_BIN) save -o out/catalog.tar $(CATALOG_IMAGE) - echo $(CATALOG_IMAGE) > ./out/catalog-name - ##@ Misc .PHONY: test-workflow