From a7ece4dc15dbccd98f4df76c84197d700fbb3a3b Mon Sep 17 00:00:00 2001 From: Andrew Lewis Date: Sun, 14 Sep 2025 20:13:30 +0200 Subject: [PATCH 1/5] Implement automatic rebuilds of release images --- .github/actions/bump_tag/action.yml | 23 ++++++++++++ .github/workflows/release.yml | 1 + .github/workflows/security.yml | 56 +++++++++++++++++++++++++---- 3 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 .github/actions/bump_tag/action.yml diff --git a/.github/actions/bump_tag/action.yml b/.github/actions/bump_tag/action.yml new file mode 100644 index 0000000..1a8a4a8 --- /dev/null +++ b/.github/actions/bump_tag/action.yml @@ -0,0 +1,23 @@ +name: Push new tag with version bump + +runs: + using: "composite" + steps: + - name: Create new patch release + shell: bash + env: + GH_TOKEN: ${{ github.token }} + run: | + cd $GITHUB_WORKSPACE + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + LATEST_TAG=`git tag --list "v[0-9]*.[0-9]*.[0-9]*\+[0-9]*" --sort=-v:refname | head -n 1` + RELEASE_VERSION=${LATEST_TAG%%+*} + BUILD_VERSION=${LATEST_TAG##*+} + NEW_BUILD_VERSION=$((BUILD_VERSION + 1)) + NEW_TAG="${RELEASE_VERSION}+${NEW_BUILD_VERSION}" + echo "Latest tag: $LATEST_TAG" + echo "New tag: $NEW_TAG" + git tag $NEW_TAG $LATEST_TAG + git push origin $NEW_TAG + gh workflow run release --ref $NEW_TAG diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5fc7068..1db7200 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,7 @@ on: push: tags: - "v[0-9]+.[0-9]+.[0-9]+\\+[0-9]+" + workflow_dispatch: concurrency: group: rspamd-docker-${{ github.ref_name }} diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 6607031..1eb8157 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -6,12 +6,54 @@ on: workflow_dispatch: jobs: - security_check: + autosecurity: runs-on: "ubuntu-22.04" steps: - - name: Run grype - uses: anchore/scan-action@v4 - with: - image: rspamd/rspamd:latest - only-fixed: true - severity-cutoff: low + - name: Check out source code + uses: actions/checkout@v4 + + - name: Download grype + uses: anchore/scan-action/download-grype@v4 + id: grype + + - name: Check image + run: | + ${{steps.grype.outputs.cmd}} --only-fixed -o json --file report_release.json ghcr.io/${{ github.repository }} + echo RELEASE_VULN_COUNT=`jq '(.matches | length)' report_release.json` >> "$GITHUB_ENV" + + - name: Check base image + if: ${{ env.RELEASE_VULN_COUNT != 0 }} + run: | + ${{steps.grype.outputs.cmd}} --only-fixed -o json --file report_base.json debian:bookworm-slim + echo BASE_VULN_COUNT=`jq '(.matches | length)' report_base.json` >> "$GITHUB_ENV" + + - name: Push new tag if base image checked clean + if: ${{ env.RELEASE_VULN_COUNT != 0 && env.BASE_VULN_COUNT == 0 }} + uses: ./.github/actions/bump_tag + permissions: + actions: write + contents: write + + - name: Check if base image is relatively better + if: ${{ env.RELEASE_VULN_COUNT != 0 && env.BASE_VULN_COUNT != 0 }} + run: | + jq '.matches.[].vulnerability.id' report_release.json | sort | uniq > release_vulns.txt + jq '.matches.[].vulnerability.id' report_base.json | sort | uniq > base_vulns.txt + NEWVULNS=$(comm -13 base_vulns.txt release_vulns.txt | wc -l) + if [ "$NEWVULNS" -gt 0 ]; then + echo "New base image has $NEWVULNS novel vulnerabilties? Weird... :(" + fi + FIXEDVULNS=$(comm -23 release_vulns.txt base_vulns.txt | wc -l) + if [ "$FIXEDVULNS" -gt 0 ]; then + echo "Found $FIXEDVULNS vulnerabilities fixed in new base image. Bumping tag." + echo "BUMP_TAG=1" >> "$GITHUB_ENV" + else + echo "Base image not fixed yet? OK... :(" + fi + + - name: Push new tag if base image is better + if: ${{ env.BUMP_TAG == 1 }} + uses: ./.github/actions/bump_tag + permissions: + actions: write + contents: write From 1908958f8100d67413a8a2c407818f5d4cd4dafa Mon Sep 17 00:00:00 2001 From: Andrew Lewis Date: Mon, 15 Sep 2025 19:49:29 +0200 Subject: [PATCH 2/5] Fix previous changes - Generate a proper image for comparison - Put workflow parameters in their proper location --- .github/workflows/security.yml | 55 +++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 1eb8157..c135da1 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -7,6 +7,9 @@ on: jobs: autosecurity: + permissions: + actions: write + contents: write runs-on: "ubuntu-22.04" steps: - name: Check out source code @@ -21,39 +24,51 @@ jobs: ${{steps.grype.outputs.cmd}} --only-fixed -o json --file report_release.json ghcr.io/${{ github.repository }} echo RELEASE_VULN_COUNT=`jq '(.matches | length)' report_release.json` >> "$GITHUB_ENV" - - name: Check base image + - name: Get old package tag if: ${{ env.RELEASE_VULN_COUNT != 0 }} run: | - ${{steps.grype.outputs.cmd}} --only-fixed -o json --file report_base.json debian:bookworm-slim - echo BASE_VULN_COUNT=`jq '(.matches | length)' report_base.json` >> "$GITHUB_ENV" + OLD_PKG_TAG=`docker inspect ghcr.io/${{ github.repository }} | jq -r '.[0].Config.Labels."com.rspamd.pkg-tag"'` + echo "OLD_PKG_TAG=$OLD_PKG_TAG" >> "$GITHUB_ENV" - - name: Push new tag if base image checked clean - if: ${{ env.RELEASE_VULN_COUNT != 0 && env.BASE_VULN_COUNT == 0 }} + - name: Build test image + if: ${{ env.RELEASE_VULN_COUNT != 0 }} + id: build_test + uses: docker/build-push-action@v5 + with: + build-args: | + PKG_IMG=ghcr.io/${{ github.repository }} + PKG_TAG=${{ env.OLD_PKG_TAG }} + file: Dockerfile + push: false + tags: "" + + - name: Check test image + if: ${{ env.RELEASE_VULN_COUNT != 0 }} + run: | + ${{steps.grype.outputs.cmd}} --only-fixed -o json --file report_test.json ${{ steps.build_test.outputs.digest }} + echo TEST_VULN_COUNT=`jq '(.matches | length)' report_test.json` >> "$GITHUB_ENV" + + - name: Push new tag if test image checked clean + if: ${{ env.RELEASE_VULN_COUNT != 0 && env.test_VULN_COUNT == 0 }} uses: ./.github/actions/bump_tag - permissions: - actions: write - contents: write - - name: Check if base image is relatively better - if: ${{ env.RELEASE_VULN_COUNT != 0 && env.BASE_VULN_COUNT != 0 }} + - name: Check if test image is relatively better + if: ${{ env.RELEASE_VULN_COUNT != 0 && env.test_VULN_COUNT != 0 }} run: | jq '.matches.[].vulnerability.id' report_release.json | sort | uniq > release_vulns.txt - jq '.matches.[].vulnerability.id' report_base.json | sort | uniq > base_vulns.txt - NEWVULNS=$(comm -13 base_vulns.txt release_vulns.txt | wc -l) + jq '.matches.[].vulnerability.id' report_test.json | sort | uniq > test_vulns.txt + NEWVULNS=$(comm -13 test_vulns.txt release_vulns.txt | wc -l) if [ "$NEWVULNS" -gt 0 ]; then - echo "New base image has $NEWVULNS novel vulnerabilties? Weird... :(" + echo "New test image has $NEWVULNS novel vulnerabilties? Weird... :(" fi - FIXEDVULNS=$(comm -23 release_vulns.txt base_vulns.txt | wc -l) + FIXEDVULNS=$(comm -23 release_vulns.txt test_vulns.txt | wc -l) if [ "$FIXEDVULNS" -gt 0 ]; then - echo "Found $FIXEDVULNS vulnerabilities fixed in new base image. Bumping tag." + echo "Found $FIXEDVULNS vulnerabilities fixed in new test image. Bumping tag." echo "BUMP_TAG=1" >> "$GITHUB_ENV" else - echo "Base image not fixed yet? OK... :(" + echo "test image not fixed yet? OK... :(" fi - - name: Push new tag if base image is better + - name: Push new tag if test image is better if: ${{ env.BUMP_TAG == 1 }} uses: ./.github/actions/bump_tag - permissions: - actions: write - contents: write From 4ff33f15cc98975bc6e1fd84c466b77340989b09 Mon Sep 17 00:00:00 2001 From: Andrew Lewis Date: Fri, 19 Sep 2025 15:20:44 +0200 Subject: [PATCH 3/5] Fix comparisons; add logging --- .github/workflows/security.yml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index c135da1..7dfea78 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -22,16 +22,18 @@ jobs: - name: Check image run: | ${{steps.grype.outputs.cmd}} --only-fixed -o json --file report_release.json ghcr.io/${{ github.repository }} - echo RELEASE_VULN_COUNT=`jq '(.matches | length)' report_release.json` >> "$GITHUB_ENV" + RELEASE_VULN_COUNT=`jq '(.matches | length)' report_release.json` + echo Counted $RELEASE_VULN_COUNT vulnerabilities in release image. + echo RELEASE_VULN_COUNT=$RELEASE_VULN_COUNT >> "$GITHUB_ENV" - name: Get old package tag - if: ${{ env.RELEASE_VULN_COUNT != 0 }} + if: ${{ env.RELEASE_VULN_COUNT != '0' }} run: | OLD_PKG_TAG=`docker inspect ghcr.io/${{ github.repository }} | jq -r '.[0].Config.Labels."com.rspamd.pkg-tag"'` echo "OLD_PKG_TAG=$OLD_PKG_TAG" >> "$GITHUB_ENV" - name: Build test image - if: ${{ env.RELEASE_VULN_COUNT != 0 }} + if: ${{ env.RELEASE_VULN_COUNT != '0' }} id: build_test uses: docker/build-push-action@v5 with: @@ -43,17 +45,19 @@ jobs: tags: "" - name: Check test image - if: ${{ env.RELEASE_VULN_COUNT != 0 }} + if: ${{ env.RELEASE_VULN_COUNT != '0' }} run: | ${{steps.grype.outputs.cmd}} --only-fixed -o json --file report_test.json ${{ steps.build_test.outputs.digest }} - echo TEST_VULN_COUNT=`jq '(.matches | length)' report_test.json` >> "$GITHUB_ENV" + TEST_VULN_COUNT=`jq '(.matches | length)' report_test.json` + echo Counted $TEST_VULN_COUNT vulnerabilities in test image. + echo TEST_VULN_COUNT=$TEST_VULN_COUNT >> "$GITHUB_ENV" - name: Push new tag if test image checked clean - if: ${{ env.RELEASE_VULN_COUNT != 0 && env.test_VULN_COUNT == 0 }} + if: ${{ env.RELEASE_VULN_COUNT != '0' && env.TEST_VULN_COUNT == '0' }} uses: ./.github/actions/bump_tag - name: Check if test image is relatively better - if: ${{ env.RELEASE_VULN_COUNT != 0 && env.test_VULN_COUNT != 0 }} + if: ${{ env.RELEASE_VULN_COUNT != '0' && env.TEST_VULN_COUNT != '0' }} run: | jq '.matches.[].vulnerability.id' report_release.json | sort | uniq > release_vulns.txt jq '.matches.[].vulnerability.id' report_test.json | sort | uniq > test_vulns.txt @@ -70,5 +74,5 @@ jobs: fi - name: Push new tag if test image is better - if: ${{ env.BUMP_TAG == 1 }} + if: ${{ env.BUMP_TAG == '1' }} uses: ./.github/actions/bump_tag From 5d158bff81a8e6f177dc618847a03b47b94203b7 Mon Sep 17 00:00:00 2001 From: Andrew Lewis Date: Fri, 3 Oct 2025 17:04:51 +0200 Subject: [PATCH 4/5] Fix tag bump --- .github/actions/bump_tag/action.yml | 2 +- .github/workflows/security.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/actions/bump_tag/action.yml b/.github/actions/bump_tag/action.yml index 1a8a4a8..aa28e13 100644 --- a/.github/actions/bump_tag/action.yml +++ b/.github/actions/bump_tag/action.yml @@ -5,10 +5,10 @@ runs: steps: - name: Create new patch release shell: bash + working-directory: ${{ github.workspace }} env: GH_TOKEN: ${{ github.token }} run: | - cd $GITHUB_WORKSPACE git config --global user.name "github-actions[bot]" git config --global user.email "github-actions[bot]@users.noreply.github.com" LATEST_TAG=`git tag --list "v[0-9]*.[0-9]*.[0-9]*\+[0-9]*" --sort=-v:refname | head -n 1` diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 7dfea78..933747c 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -14,6 +14,8 @@ jobs: steps: - name: Check out source code uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Download grype uses: anchore/scan-action/download-grype@v4 From 2dbdd7c3d574a3ab3fe5376c82672f923a17d576 Mon Sep 17 00:00:00 2001 From: Andrew Lewis Date: Tue, 21 Oct 2025 15:16:33 +0200 Subject: [PATCH 5/5] Fix inverted logic; spelling --- .github/workflows/security.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 933747c..aa3b0fc 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -63,9 +63,9 @@ jobs: run: | jq '.matches.[].vulnerability.id' report_release.json | sort | uniq > release_vulns.txt jq '.matches.[].vulnerability.id' report_test.json | sort | uniq > test_vulns.txt - NEWVULNS=$(comm -13 test_vulns.txt release_vulns.txt | wc -l) + NEWVULNS=$(comm -23 test_vulns.txt release_vulns.txt | wc -l) if [ "$NEWVULNS" -gt 0 ]; then - echo "New test image has $NEWVULNS novel vulnerabilties? Weird... :(" + echo "New test image has $NEWVULNS novel vulnerabilities? Weird... :(" fi FIXEDVULNS=$(comm -23 release_vulns.txt test_vulns.txt | wc -l) if [ "$FIXEDVULNS" -gt 0 ]; then