Skip to content
Merged
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
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
*

# Include
!alpine-packages.txt
!Dockerfile
!entrypoint.sh
!LICENSE
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: (Auto) Create Pull Request
name: (Auto) Pull Request Create

on:
push:
Expand All @@ -14,7 +14,7 @@ permissions:

jobs:
call:
uses: devops-infra/.github/.github/workflows/reusable-auto-create-pull-request.yml@v1
uses: devops-infra/.github/.github/workflows/reusable-auto-pull-request-create.yml@v1
with:
profile: actions
secrets: inherit
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: (Cron) Weekly repository health
name: (Cron) Dependency Update

on:
schedule:
Expand All @@ -12,7 +12,7 @@ permissions:

jobs:
call:
uses: devops-infra/.github/.github/workflows/reusable-cron-check-dependencies.yml@v1
uses: devops-infra/.github/.github/workflows/reusable-cron-dependency-update.yml@v1
with:
profile: actions
secrets: inherit
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: (Manual) Update Version
name: (Manual) Release Create

on:
workflow_dispatch:
Expand Down Expand Up @@ -30,7 +30,7 @@ permissions:

jobs:
call:
uses: devops-infra/.github/.github/workflows/reusable-manual-update-version.yml@v1
uses: devops-infra/.github/.github/workflows/reusable-manual-release-create.yml@v1
with:
bump-type: ${{ inputs.type }}
explicit-version: ${{ inputs.version }}
Expand Down
17 changes: 9 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
FROM alpine:3.23
FROM alpine:3.23.3

# Multi-architecture from buildx
ARG TARGETARCH
# renovate: datasource=github-releases depName=GoogleContainerTools/container-structure-test

# GoogleContainerTools/container-structure-test
ARG CST_VERSION=v1.22.1

# Copy all needed files
COPY entrypoint.sh /
COPY alpine-packages.txt /tmp/alpine-packages.txt

# Install needed packages
SHELL ["/bin/sh", "-euxo", "pipefail", "-c"]
# hadolint ignore=DL3018
RUN set -eux; \
apk add --no-cache \
bash \
curl \
jq; \
xargs -r apk add --no-cache < /tmp/alpine-packages.txt; \
chmod +x /entrypoint.sh; \
targetarch="${TARGETARCH:-}" ;\
if [ -z "${targetarch}" ]; then \
Expand All @@ -36,8 +36,9 @@ RUN set -eux; \
actual_sha="$(sha256sum /usr/local/bin/container-structure-test | awk '{print $1}')" ;\
[ "${actual_sha}" = "${expected_sha}" ] ;\
chmod +x /usr/local/bin/container-structure-test ;\
rm -f /tmp/checksums.txt ;\
rm -rf /var/cache/apk/* ;\
rm -rf /var/cache/* ;\
rm -rf /root/.cache/* ;\
rm -rf /tmp/* ;\
container-structure-test version

# Finish up
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Check also other actions from [DevOps-Infra](https://shyper.pro/portfolio/projec
[
![GitHub repo](https://img.shields.io/badge/GitHub-devops--infra%2Faction--container--structure--test-blueviolet.svg?style=plastic&logo=github)
![GitHub last commit](https://img.shields.io/github/last-commit/devops-infra/action-container-structure-test?color=blueviolet&logo=github&style=plastic&label=Last%20commit)
![Pull Request](https://github.com/devops-infra/action-container-structure-test/actions/workflows/auto-create-pull-request.yml/badge.svg)
![Pull Request](https://github.com/devops-infra/action-container-structure-test/actions/workflows/auto-pull-request-create.yml/badge.svg)
![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/devops-infra/action-container-structure-test?color=blueviolet&label=Code%20size&style=plastic&logo=github)
![GitHub license](https://img.shields.io/github/license/devops-infra/action-container-structure-test?color=blueviolet&logo=github&style=plastic&label=License)
](https://github.com/devops-infra/action-container-structure-test "shields.io")
Expand All @@ -34,7 +34,7 @@ Check also other actions from [DevOps-Infra](https://shyper.pro/portfolio/projec
![Docker version](https://img.shields.io/docker/v/devopsinfra/action-container-structure-test?color=blue&label=Version&logo=docker&style=plastic&sort=semver)
![Image size](https://img.shields.io/docker/image-size/devopsinfra/action-container-structure-test/latest?label=Image%20size&style=plastic&logo=docker)
![Docker Pulls](https://img.shields.io/docker/pulls/devopsinfra/action-container-structure-test?color=blue&label=Pulls&logo=docker&style=plastic)
![Weekly Health](https://github.com/devops-infra/action-container-structure-test/actions/workflows/cron-check-dependencies.yml/badge.svg)
![Weekly Health](https://github.com/devops-infra/action-container-structure-test/actions/workflows/cron-dependency-update.yml/badge.svg)
](https://hub.docker.com/r/devopsinfra/action-container-structure-test "shields.io")


Expand Down Expand Up @@ -265,7 +265,7 @@ Full documentation: [GoogleContainerTools/container-structure-test](https://gith

## 🏗️ CI/CD
Workflows included:
- (Auto) Create Pull Request (`.github/workflows/auto-create-pull-request.yml`)
- (Auto) Pull Request Create (`.github/workflows/auto-pull-request-create.yml`)
- Trigger: push to any branch except `master` and `dependabot/**`.
- Jobs:
- Lint
Expand All @@ -279,12 +279,12 @@ Workflows included:
- Build and push multi-platform image, and inspect manifest
- Publish GitHub Release
- Update Docker hub description
- (Cron) Weekly dependency build (`.github/workflows/cron-check-dependencies.yml`)
- (Cron) Weekly dependency build (`.github/workflows/cron-dependency-update.yml`)
- Trigger: Weekly on Monday at 08:00 UTC
- Jobs:
- Lint
- Build and push multi-platform test image, and inspect manifest
- (Manual) Update version (`.github/workflows/manual-update-version.yml`)
- (Manual) Update version (`.github/workflows/manual-release-create.yml`)
- Trigger: manual `workflow_dispatch` with `type` (`patch|minor|major|set`) xor `version` when `type=set`
pushes to `release/**` branch and creates a pull request to create a new release
- Jobs:
Expand Down
53 changes: 6 additions & 47 deletions Taskfile.cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,10 @@ tasks:
exit $rc
fi

version:get:
desc: Get current version
cmds:
- echo "{{.VERSION}}"

update-versions:
desc: Check latest CST release and update Dockerfile ARG
dependency:update:
desc: Update repository dependencies not covered by dependabot
cmds:
- task: scripts:packages:update
- |
set -eu
latest="$(curl -LsS https://api.github.com/repos/GoogleContainerTools/container-structure-test/releases/latest | jq -r '.tag_name')"
Expand Down Expand Up @@ -309,44 +305,7 @@ tasks:
- git config user.name "github-actions[bot]"
- git config user.email "github-actions[bot]@users.noreply.github.com"

sync:all:
desc: Sync all common files
cmds:
- task sync:configs
- task sync:ignores
- task sync:taskfiles

sync:configs:
desc: Sync configuration files with devops-infra/.github
cmds:
- |
echo "▶️ Syncing configuration files from devops-infra/.github..."
curl -fsSL {{.CONFIGS_BASE_URL}}/.editorconfig -o ./.editorconfig
curl -fsSL {{.CONFIGS_BASE_URL}}/.hadolint.yaml -o ./.hadolint.yaml
curl -fsSL {{.CONFIGS_BASE_URL}}/.pre-commit-config.yaml -o ./.pre-commit-config.yaml
curl -fsSL {{.CONFIGS_BASE_URL}}/.shellcheckrc -o ./.shellcheckrc
curl -fsSL {{.CONFIGS_BASE_URL}}/.yamllint.yml -o ./.yamllint.yml
git add .editorconfig .hadolint.yaml .pre-commit-config.yaml .shellcheckrc .yamllint.yml
echo "✅ Synced configuration files"

sync:ignores:
desc: Sync ignore files with devops-infra/.github
cmds:
- |
echo "▶️ Syncing ignore files from devops-infra/.github..."
curl -fsSL {{.CONFIGS_BASE_URL}}/.gitignore -o ./.gitignore
curl -fsSL {{.CONFIGS_BASE_URL}}/.dockerignore -o ./.dockerignore
git add .gitignore .dockerignore
echo "✅ Synced ignore files"

sync:taskfiles:
desc: Sync Taskfiles with devops-infra/.github
version:get:
desc: Get current version
cmds:
- |
echo "▶️ Syncing Taskfiles from devops-infra/.github..."
curl -fsSL {{.TASKFILES_BASE_URL}}/Taskfile.yml -o ./Taskfile.yml
curl -fsSL {{.TASKFILES_BASE_URL}}/Taskfile.cicd.yml -o ./Taskfile.cicd.yml
curl -fsSL {{.TASKFILES_BASE_URL}}/Taskfile.docker.yml -o ./Taskfile.docker.yml
curl -fsSL {{.TASKFILES_BASE_URL}}/Taskfile.variables.yml -o ./Taskfile.variables.yml
git add Taskfile*.yml
echo "✅ Synced Taskfiles"
- echo "{{.VERSION}}"
148 changes: 148 additions & 0 deletions Taskfile.scripts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
version: '3'

silent: true

tasks:
help:
desc: Detailed help
cmds:
- |
echo "Tasks:"
task --list
echo ""
echo "Environment:"
echo " DOCKER_NAME={{.DOCKER_NAME}} DOCKER_USERNAME={{.DOCKER_USERNAME}}"
echo " GHRC_NAME={{.GHRC_NAME}} GITHUB_USERNAME={{.GITHUB_USERNAME}}"
echo " LAST_RELEASE={{.LAST_RELEASE}}" VERSION={{.VERSION}} VERSION_FULL={{.VERSION_FULL}}
echo " BRANCH={{.GIT_BRANCH}} GIT_SHORT_SHA={{.GIT_SHORT_SHA}}" GIT_SHA={{.GIT_SHA}}

packages:update:
desc: Update Alpine package pins in alpine-packages.txt
cmds:
- |
set -eu
if [ ! -f Dockerfile ]; then
echo "INFO: Dockerfile not found; nothing to update"
exit 0
fi
if [ ! -f alpine-packages.txt ]; then
echo "INFO: alpine-packages.txt not found; nothing to update"
exit 0
fi

base_image="$(sed -nE 's/^FROM[[:space:]]+([^[:space:]]+).*/\1/p' Dockerfile | head -1)"
if [ -z "$base_image" ]; then
echo "INFO: Could not resolve base image; nothing to update"
exit 0
fi

case "$base_image" in
alpine:*|alpine)
:
;;
*)
echo "INFO: Base image is '$base_image', not Alpine; nothing to update"
exit 0
;;
esac

alpine_line="${base_image#alpine:}"
if [ "$alpine_line" = "$base_image" ] || [ -z "$alpine_line" ]; then
echo "INFO: Could not parse Alpine version from '$base_image'; nothing to update"
exit 0
fi
alpine_minor="$(printf '%s' "$alpine_line" | awk -F. '{print $1 "." $2}')"
if ! printf '%s' "$alpine_minor" | grep -Eq '^[0-9]+\.[0-9]+$'; then
echo "INFO: Unsupported Alpine version '$alpine_line'; nothing to update"
exit 0
fi
alpine_repo="v${alpine_minor}"
arch="x86_64"

normalize_minor() {
version="$1"
printf '%s' "$version" | sed -E 's/^([0-9]+\.[0-9]+).*/\1/'
}

fetch_index() {
repo="$1"
out="$2"
url="https://dl-cdn.alpinelinux.org/alpine/${alpine_repo}/${repo}/${arch}/APKINDEX.tar.gz"
curl --fail --silent --show-error "$url" | tar -O -zx APKINDEX > "$out"
}

lookup_latest() {
pkg="$1"
for index in "$index_main" "$index_community"; do
found="$(awk -v pkg="$pkg" '
BEGIN { RS=""; FS="\n" }
{
p=""; v=""
for (i=1; i<=NF; i++) {
if ($i ~ /^P:/) p=substr($i,3)
if ($i ~ /^V:/) v=substr($i,3)
}
if (p==pkg) { print v; exit }
}
' "$index")"
if [ -n "$found" ]; then
printf '%s' "$found"
return 0
fi
done
return 1
}

mkdir -p .tmp
index_main=".tmp/apkindex-main-${alpine_repo}-${arch}.txt"
index_community=".tmp/apkindex-community-${alpine_repo}-${arch}.txt"
fetch_index main "$index_main"
fetch_index community "$index_community"

if ! grep -Eq '^[a-zA-Z0-9+_.-]+(=~|~=)[0-9]+\.[0-9]+$' alpine-packages.txt; then
echo "INFO: No pinned Alpine packages (~=X.Y) found in alpine-packages.txt"
exit 0
fi

tmp_out=".tmp/alpine-packages.updated.txt"
: > "$tmp_out"
updated=0
while IFS= read -r line || [ -n "$line" ]; do
if [ -z "$line" ] || printf '%s' "$line" | grep -Eq '^[[:space:]]*#'; then
echo "$line" >> "$tmp_out"
continue
fi
if ! printf '%s' "$line" | grep -Eq '^[a-zA-Z0-9+_.-]+(=~|~=)[0-9]+\.[0-9]+$'; then
echo "$line" >> "$tmp_out"
continue
fi

pkg="$(printf '%s' "$line" | sed -E 's/^([a-zA-Z0-9+_.-]+)(=~|~=).*/\1/')"
current_minor="$(printf '%s' "$line" | sed -E 's/^[a-zA-Z0-9+_.-]+(=~|~=)([0-9]+\.[0-9]+).*$/\2/')"
latest_full="$(lookup_latest "$pkg" || true)"
if [ -z "$latest_full" ]; then
echo "WARN: Could not resolve latest version for $pkg; keeping $line"
echo "$line" >> "$tmp_out"
continue
fi

latest_minor="$(normalize_minor "$latest_full")"
if [ "$latest_minor" = "$current_minor" ]; then
echo "OK: $pkg already up to date at $current_minor"
echo "$pkg~=$current_minor" >> "$tmp_out"
continue
fi
echo "UPDATE: $pkg $current_minor -> $latest_minor"
echo "$pkg~=$latest_minor" >> "$tmp_out"
updated=1
done < alpine-packages.txt

if ! cmp -s alpine-packages.txt "$tmp_out"; then
mv "$tmp_out" alpine-packages.txt
else
rm -f "$tmp_out"
fi

if [ "$updated" -eq 0 ]; then
echo "INFO: No Alpine package updates were required"
fi
11 changes: 2 additions & 9 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ silent: true

includes:
variables: ./Taskfile.variables.yml
scripts: ./Taskfile.scripts.yml
cicd:
taskfile: ./Taskfile.cicd.yml
flatten: true
Expand All @@ -21,12 +22,4 @@ tasks:
help:
desc: Detailed help
cmds:
- |
echo "Tasks:"
task --list
echo ""
echo "Environment:"
echo " DOCKER_NAME={{.DOCKER_NAME}} DOCKER_USERNAME={{.DOCKER_USERNAME}}"
echo " GHRC_NAME={{.GHRC_NAME}} GITHUB_USERNAME={{.GITHUB_USERNAME}}"
echo " LAST_RELEASE={{.LAST_RELEASE}}" VERSION={{.VERSION}} VERSION_FULL={{.VERSION_FULL}}
echo " BRANCH={{.GIT_BRANCH}} GIT_SHORT_SHA={{.GIT_SHORT_SHA}}" GIT_SHA={{.GIT_SHA}}
- task: scripts:help
3 changes: 3 additions & 0 deletions alpine-packages.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
bash~=5.3
curl~=8.17
jq~=1.8
Loading