forked from repo-mirrors/cnpg-postgres-containers
feat: immutable digest for the most specific tags (#113)
Detect updates of the Dockerfile template and Barman python dependencies, and increase the imageReleaseVersion accordingly. Avoid pushing an image if its most specific tag (fullTag) already exists, thus preventing the override of the existing digest. Signed-off-by: Niccolò Fei <niccolo.fei@enterprisedb.com>
This commit is contained in:
32
.github/workflows/build.yml
vendored
32
.github/workflows/build.yml
vendored
@@ -72,8 +72,29 @@ jobs:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# When publishing new images from main, we should not overwrite an existing
|
||||
# tag in order to guarantee the tag's SHA digest consistency.
|
||||
- name: Verify primary tag is not overwritten
|
||||
run: |
|
||||
echo "MISSING_TAG=false" >> $GITHUB_ENV
|
||||
# if we are not on the main branch, always push
|
||||
if [ "${GITHUB_REF#refs/heads/}" != main ]; then
|
||||
echo "MISSING_TAG=true" >> $GITHUB_ENV
|
||||
exit 0
|
||||
fi
|
||||
IMAGE="${IMAGE_RELEASE}:${{ matrix.fullTag }}"
|
||||
# If the primary tag already exists, skip the building phase
|
||||
if skopeo inspect docker://${IMAGE} >/dev/null 2>/dev/null; then
|
||||
echo "Image ${IMAGE} already exists"
|
||||
# We still need to grab the digest to build the imageCatalog
|
||||
echo "OLD_DIGEST=$(skopeo inspect docker://${IMAGE} --format '{{ .Digest }}')" >> $GITHUB_ENV
|
||||
else
|
||||
echo "MISSING_TAG=true" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Build and load
|
||||
uses: docker/build-push-action@v6
|
||||
if: ${{ env.MISSING_TAG == 'true' }}
|
||||
with:
|
||||
context: ${{ matrix.dir }}
|
||||
file: ${{ matrix.file }}
|
||||
@@ -83,6 +104,7 @@ jobs:
|
||||
|
||||
- name: Dockle scan
|
||||
uses: erzz/dockle-action@v1
|
||||
if: ${{ env.MISSING_TAG == 'true' }}
|
||||
with:
|
||||
image: "${{ env.IMAGE_STAGING }}:${{ matrix.tags[0] }}"
|
||||
exit-code: '1'
|
||||
@@ -92,6 +114,7 @@ jobs:
|
||||
|
||||
- name: Run Snyk to check Docker image for vulnerabilities
|
||||
uses: snyk/actions/docker@master
|
||||
if: ${{ env.MISSING_TAG == 'true' }}
|
||||
continue-on-error: true
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
@@ -101,6 +124,7 @@ jobs:
|
||||
|
||||
- name: Upload result to GitHub Code Scanning
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
if: ${{ env.MISSING_TAG == 'true' }}
|
||||
continue-on-error: true
|
||||
with:
|
||||
sarif_file: snyk.sarif
|
||||
@@ -108,6 +132,7 @@ jobs:
|
||||
- name: Build and push
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
if: ${{ env.MISSING_TAG == 'true' }}
|
||||
with:
|
||||
context: ${{ matrix.dir }}
|
||||
file: ${{ matrix.file }}
|
||||
@@ -123,7 +148,12 @@ jobs:
|
||||
BASE_IMAGE=${IMAGE_RELEASE}
|
||||
fi
|
||||
|
||||
IMAGE=${BASE_IMAGE}:${{ matrix.fullTag }}@${{ steps.build.outputs.digest }} \
|
||||
DIGEST="${{ steps.build.outputs.digest }}"
|
||||
if [[ "${{ env.MISSING_TAG }}" == "false" ]]; then
|
||||
DIGEST="${{ env.OLD_DIGEST }}"
|
||||
fi
|
||||
|
||||
IMAGE=${BASE_IMAGE}:${{ matrix.fullTag }}@${DIGEST} \
|
||||
MAJOR=${{ matrix.version }} \
|
||||
yq --null-input '{
|
||||
"apiVersion": "postgresql.cnpg.io/v1",
|
||||
|
@@ -90,6 +90,14 @@ generate_postgres() {
|
||||
pipOptions="--break-system-packages"
|
||||
fi
|
||||
|
||||
dockerTemplate="Dockerfile.template"
|
||||
if [[ ${version} -gt "${POSTGRESQL_LATEST_MAJOR_RELEASE}" ]]; then
|
||||
dockerTemplate="Dockerfile-beta.template"
|
||||
fi
|
||||
|
||||
# Update requirements.txt
|
||||
echo "$requirements" > "$versionDir/requirements.txt"
|
||||
|
||||
# Output the image being updated
|
||||
echo "$postgresImageVersion"
|
||||
|
||||
@@ -111,9 +119,9 @@ generate_postgres() {
|
||||
|
||||
newRelease="false"
|
||||
|
||||
# Detect if postgres image updated
|
||||
# Detect an update of the postgres image
|
||||
if [ "$oldPostgresImageLastUpdate" != "$postgresImageLastUpdate" ]; then
|
||||
echo "Debian Image changed from $oldPostgresImageLastUpdate to $postgresImageLastUpdate"
|
||||
echo "Postgres image timestamp changed from $oldPostgresImageLastUpdate to $postgresImageLastUpdate"
|
||||
newRelease="true"
|
||||
record_version "${versionFile}" "POSTGRES_IMAGE_LAST_UPDATED" "${postgresImageLastUpdate}"
|
||||
fi
|
||||
@@ -125,6 +133,18 @@ generate_postgres() {
|
||||
record_version "${versionFile}" "BARMAN_VERSION" "${barmanVersion}"
|
||||
fi
|
||||
|
||||
# Detect an update of Dockerfile template
|
||||
if [[ -n $(git diff --name-status "$dockerTemplate") ]]; then
|
||||
echo "Detected update of $dockerTemplate"
|
||||
newRelease="true"
|
||||
fi
|
||||
|
||||
# Detect an update of requirements.txt
|
||||
if [[ -n $(git diff --name-status "$versionDir/requirements.txt") ]]; then
|
||||
echo "Detected update of requirements.txt dependencies"
|
||||
newRelease="true"
|
||||
fi
|
||||
|
||||
if [ "$oldPostgresImageVersion" != "$postgresImageVersion" ]; then
|
||||
echo "PostgreSQL base image changed from $oldPostgresImageVersion to $postgresImageVersion"
|
||||
record_version "${versionFile}" "IMAGE_RELEASE_VERSION" 1
|
||||
@@ -135,12 +155,6 @@ generate_postgres() {
|
||||
record_version "${versionFile}" "IMAGE_RELEASE_VERSION" $imageReleaseVersion
|
||||
fi
|
||||
|
||||
dockerTemplate="Dockerfile.template"
|
||||
if [[ ${version} -gt "${POSTGRESQL_LATEST_MAJOR_RELEASE}" ]]; then
|
||||
dockerTemplate="Dockerfile-beta.template"
|
||||
fi
|
||||
|
||||
echo "$requirements" > "$versionDir/requirements.txt"
|
||||
sed -e 's/%%POSTGRES_IMAGE_VERSION%%/'"$postgresImageVersion"'/g' \
|
||||
-e 's/%%IMAGE_RELEASE_VERSION%%/'"$imageReleaseVersion"'/g' \
|
||||
-e 's/%%PIP_OPTIONS%%/'"${pipOptions}"'/g' \
|
||||
|
Reference in New Issue
Block a user