From 77164647f2202cec252610d4d2944fb23a367e02 Mon Sep 17 00:00:00 2001 From: ChristophShyper <45788587+ChristophShyper@users.noreply.github.com> Date: Wed, 15 Apr 2026 20:16:13 +0200 Subject: [PATCH 1/3] feat: rename workflow files and update references for clarity --- .github/workflows/README.md | 14 +- ...quest.yml => auto-pull-request-create.yml} | 8 +- ...dencies.yml => cron-dependency-update.yml} | 4 +- ...-version.yml => manual-release-create.yml} | 4 +- ... => reusable-auto-pull-request-create.yml} | 2 +- ...ml => reusable-cron-dependency-update.yml} | 39 +++-- ...yml => reusable-manual-release-create.yml} | 2 +- Taskfile.cicd.yml | 8 + templates/actions/taskfiles/Taskfile.cicd.yml | 8 + .../actions/taskfiles/Taskfile.scripts.yml | 150 ++++++++++++++++++ templates/actions/taskfiles/Taskfile.yml | 11 +- ...quest.yml => auto-pull-request-create.yml} | 4 +- ...dencies.yml => cron-dependency-update.yml} | 4 +- ...-version.yml => manual-release-create.yml} | 4 +- .../dockerized/taskfiles/Taskfile.cicd.yml | 8 + .../dockerized/taskfiles/Taskfile.scripts.yml | 63 ++++++++ ...quest.yml => auto-pull-request-create.yml} | 4 +- ...dencies.yml => cron-dependency-update.yml} | 4 +- ...-version.yml => manual-release-create.yml} | 4 +- templates/other/taskfiles/Taskfile.cicd.yml | 8 + ...quest.yml => auto-pull-request-create.yml} | 4 +- ...dencies.yml => cron-dependency-update.yml} | 4 +- ...-version.yml => manual-release-create.yml} | 4 +- templates/static/taskfiles/Taskfile.cicd.yml | 8 + ...quest.yml => auto-pull-request-create.yml} | 4 +- ...dencies.yml => cron-dependency-update.yml} | 4 +- ...-version.yml => manual-release-create.yml} | 4 +- 27 files changed, 314 insertions(+), 71 deletions(-) rename .github/workflows/{auto-create-pull-request.yml => auto-pull-request-create.yml} (61%) rename .github/workflows/{cron-check-dependencies.yml => cron-dependency-update.yml} (74%) rename .github/workflows/{manual-update-version.yml => manual-release-create.yml} (90%) rename .github/workflows/{reusable-auto-create-pull-request.yml => reusable-auto-pull-request-create.yml} (98%) rename .github/workflows/{reusable-cron-check-dependencies.yml => reusable-cron-dependency-update.yml} (96%) rename .github/workflows/{reusable-manual-update-version.yml => reusable-manual-release-create.yml} (99%) create mode 100644 templates/actions/taskfiles/Taskfile.scripts.yml rename templates/actions/workflows/{auto-create-pull-request.yml => auto-pull-request-create.yml} (64%) rename templates/actions/workflows/{cron-check-dependencies.yml => cron-dependency-update.yml} (64%) rename templates/actions/workflows/{manual-update-version.yml => manual-release-create.yml} (94%) rename templates/dockerized/workflows/{auto-create-pull-request.yml => auto-pull-request-create.yml} (64%) rename templates/dockerized/workflows/{cron-check-dependencies.yml => cron-dependency-update.yml} (64%) rename templates/dockerized/workflows/{manual-update-version.yml => manual-release-create.yml} (94%) rename templates/other/workflows/{auto-create-pull-request.yml => auto-pull-request-create.yml} (64%) rename templates/other/workflows/{cron-check-dependencies.yml => cron-dependency-update.yml} (63%) rename templates/other/workflows/{manual-update-version.yml => manual-release-create.yml} (94%) rename templates/static/workflows/{auto-create-pull-request.yml => auto-pull-request-create.yml} (64%) rename templates/static/workflows/{cron-check-dependencies.yml => cron-dependency-update.yml} (64%) rename templates/static/workflows/{manual-update-version.yml => manual-release-create.yml} (94%) diff --git a/.github/workflows/README.md b/.github/workflows/README.md index c8adc8b..0c68c95 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -17,9 +17,9 @@ Reusable callers exist for four profiles: Each in-scope repository should expose these caller workflows in `.github/workflows/`: -1. `auto-create-pull-request.yml` -2. `cron-check-dependencies.yml` -3. `manual-update-version.yml` +1. `auto-pull-request-create.yml` +2. `cron-dependency-update.yml` +3. `manual-release-create.yml` Static profile repositories should also expose: @@ -36,12 +36,12 @@ Example: ```yaml 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 ``` ## Weekly health workflow behavior -`cron-check-dependencies` is the aggregated weekly check. It combines: +`cron-dependency-update` is the aggregated weekly check. It combines: - dependency checks - baseline validation @@ -50,9 +50,9 @@ jobs: The workflow creates or updates one repository issue with findings and auto-closes it when clean. -## Manual version update behavior +## Manual release behavior -`manual-update-version` supports two modes: +`manual-release-create` supports two modes: - bump or set version (and open release PR) - build/push only without version bump (`build_only: true`) diff --git a/.github/workflows/auto-create-pull-request.yml b/.github/workflows/auto-pull-request-create.yml similarity index 61% rename from .github/workflows/auto-create-pull-request.yml rename to .github/workflows/auto-pull-request-create.yml index f7ee789..361314c 100644 --- a/.github/workflows/auto-create-pull-request.yml +++ b/.github/workflows/auto-pull-request-create.yml @@ -1,4 +1,4 @@ -name: (Auto) Create Pull Request +name: (Auto) Pull Request Create on: push: @@ -13,10 +13,10 @@ permissions: pull-requests: write jobs: - call-auto-create-pull-request: - uses: ./.github/workflows/reusable-auto-create-pull-request.yml + call-auto-pull-request-create: + uses: ./.github/workflows/reusable-auto-pull-request-create.yml with: runs-on: ubuntu-24.04-arm - task-version: 3.49 + task-version: 3.x profile: other secrets: inherit diff --git a/.github/workflows/cron-check-dependencies.yml b/.github/workflows/cron-dependency-update.yml similarity index 74% rename from .github/workflows/cron-check-dependencies.yml rename to .github/workflows/cron-dependency-update.yml index 66f9e15..0ffd454 100644 --- a/.github/workflows/cron-check-dependencies.yml +++ b/.github/workflows/cron-dependency-update.yml @@ -1,4 +1,4 @@ -name: (Cron) Check dependencies +name: (Cron) Dependency Update on: schedule: @@ -13,7 +13,7 @@ permissions: jobs: call-weekly-health-check: - uses: ./.github/workflows/reusable-cron-check-dependencies.yml + uses: ./.github/workflows/reusable-cron-dependency-update.yml with: runs-on: ubuntu-24.04-arm task-version: 3.x diff --git a/.github/workflows/manual-update-version.yml b/.github/workflows/manual-release-create.yml similarity index 90% rename from .github/workflows/manual-update-version.yml rename to .github/workflows/manual-release-create.yml index 868258d..fc2a897 100644 --- a/.github/workflows/manual-update-version.yml +++ b/.github/workflows/manual-release-create.yml @@ -1,4 +1,4 @@ -name: (Manual) Update Version +name: (Manual) Release Create on: workflow_dispatch: @@ -30,7 +30,7 @@ permissions: jobs: call-version-update: - uses: ./.github/workflows/reusable-manual-update-version.yml + uses: ./.github/workflows/reusable-manual-release-create.yml with: runs-on: ubuntu-24.04-arm task-version: 3.x diff --git a/.github/workflows/reusable-auto-create-pull-request.yml b/.github/workflows/reusable-auto-pull-request-create.yml similarity index 98% rename from .github/workflows/reusable-auto-create-pull-request.yml rename to .github/workflows/reusable-auto-pull-request-create.yml index 56ab0d3..81b5caf 100644 --- a/.github/workflows/reusable-auto-create-pull-request.yml +++ b/.github/workflows/reusable-auto-pull-request-create.yml @@ -1,4 +1,4 @@ -name: (Reusable - Auto) Create Pull Request +name: (Reusable - Auto) Pull Request Create on: workflow_call: diff --git a/.github/workflows/reusable-cron-check-dependencies.yml b/.github/workflows/reusable-cron-dependency-update.yml similarity index 96% rename from .github/workflows/reusable-cron-check-dependencies.yml rename to .github/workflows/reusable-cron-dependency-update.yml index 02cdebf..22d6f96 100644 --- a/.github/workflows/reusable-cron-check-dependencies.yml +++ b/.github/workflows/reusable-cron-dependency-update.yml @@ -1,4 +1,4 @@ -name: (Reusable - Cron) Check dependencies +name: (Cron) Dependency Update on: workflow_call: @@ -38,7 +38,7 @@ permissions: issues: read jobs: - dependency-check: + dependency-update: name: Weekly health scan runs-on: ${{ inputs.runs-on }} steps: @@ -70,31 +70,16 @@ jobs: echo "REPORT_FILE=$REPORT_FILE" >> "$GITHUB_ENV" echo "HAS_FINDINGS=false" >> "$GITHUB_ENV" - - name: Run lint - id: lint - if: inputs.enable-lint - continue-on-error: true - run: task lint - - - name: Record lint findings - if: inputs.enable-lint && steps.lint.outcome != 'success' - run: | - echo "- lint failed: \`task lint\`" >> "$REPORT_FILE" - echo "HAS_FINDINGS=true" >> "$GITHUB_ENV" - - - name: Run dependency checks + - name: Run dependency update task id: deps continue-on-error: true run: | set +e - if task --list | grep -q "deps:check"; then - task deps:check - rc=$? - elif task --list | grep -q "update-versions"; then - task update-versions + if task --list | grep -q "dependency:update"; then + task dependency:update rc=$? else - echo "No dedicated dependency-check task found" + echo "No dedicated dependency update task found (missing task: dependency:update)" rc=3 fi set -e @@ -106,6 +91,18 @@ jobs: echo "- dependency checks reported updates or failed" >> "$REPORT_FILE" echo "HAS_FINDINGS=true" >> "$GITHUB_ENV" + - name: Run lint + id: lint + if: inputs.enable-lint + continue-on-error: true + run: task lint + + - name: Record lint findings + if: inputs.enable-lint && steps.lint.outcome != 'success' + run: | + echo "- lint failed: \`task lint\`" >> "$REPORT_FILE" + echo "HAS_FINDINGS=true" >> "$GITHUB_ENV" + - name: Install Docker Buildx if: inputs.profile == 'actions' || inputs.profile == 'dockerized' uses: docker/setup-buildx-action@v4 diff --git a/.github/workflows/reusable-manual-update-version.yml b/.github/workflows/reusable-manual-release-create.yml similarity index 99% rename from .github/workflows/reusable-manual-update-version.yml rename to .github/workflows/reusable-manual-release-create.yml index 1b3403f..209ce8a 100644 --- a/.github/workflows/reusable-manual-update-version.yml +++ b/.github/workflows/reusable-manual-release-create.yml @@ -1,4 +1,4 @@ -name: (Reusable - Manual) Update Version +name: (Reusable - Manual) Release Create on: workflow_call: diff --git a/Taskfile.cicd.yml b/Taskfile.cicd.yml index 21057a6..26a6e1b 100644 --- a/Taskfile.cicd.yml +++ b/Taskfile.cicd.yml @@ -115,6 +115,14 @@ tasks: cmds: - echo "{{.VERSION}}" + dependency:update: + desc: Check main dependency not covered by dependabot + cmds: + - | + echo "ℹ️ No dedicated dependency updater configured for this repository." + echo "ℹ️ Dependabot handles GitHub Actions and package metadata updates." + echo "ℹ️ Keeping dependency checks as a safe no-op for now." + version:set: desc: Validate version cmds: diff --git a/templates/actions/taskfiles/Taskfile.cicd.yml b/templates/actions/taskfiles/Taskfile.cicd.yml index a35e139..17a702b 100644 --- a/templates/actions/taskfiles/Taskfile.cicd.yml +++ b/templates/actions/taskfiles/Taskfile.cicd.yml @@ -95,6 +95,14 @@ tasks: cmds: - echo "{{.VERSION}}" + dependency:update: + desc: Check main dependency not covered by dependabot + cmds: + - | + echo "ℹ️ No dedicated dependency updater configured for this repository profile." + echo "ℹ️ Dependabot handles GitHub Actions and package metadata updates." + echo "ℹ️ Docker builds still validate runtime dependencies during CI." + version:set: desc: Update version in README.md and action.yml cmds: diff --git a/templates/actions/taskfiles/Taskfile.scripts.yml b/templates/actions/taskfiles/Taskfile.scripts.yml new file mode 100644 index 0000000..3a24938 --- /dev/null +++ b/templates/actions/taskfiles/Taskfile.scripts.yml @@ -0,0 +1,150 @@ +version: '3' + +silent: true + +tasks: + help: + desc: Detailed help + cmds: + - | + echo "Tasks:" + task --list + + lint:actionlint: + desc: Lint GitHub Actions workflows with actionlint + cmds: + - | + echo "▶️ Running actionlint..." + set +e + docker run --rm -i -v "$PWD:/work" -w /work rhysd/actionlint:latest -color + rc=$? + set -e + if [ "$rc" -eq 0 ]; then + echo "✅ actionlint passed" + else + echo "❌ actionlint failed" + exit $rc + fi + + lint:hadolint: + desc: Lint Dockerfile with hadolint + cmds: + - | + echo "▶️ Running hadolint..." + set +e + docker run --rm -i -v "$PWD:/work" -w /work hadolint/hadolint:latest-debian < Dockerfile + rc=$? + set -e + if [ "$rc" -eq 0 ]; then + echo "✅ hadolint passed" + else + echo "❌ hadolint failed" + exit $rc + fi + + lint:shellcheck: + desc: Lint shell scripts with shellcheck + cmds: + - | + echo "▶️ Running shellcheck..." + set +e + docker run --rm -i -v "$PWD:/work" -w /work koalaman/shellcheck:stable -x -S style entrypoint.sh + rc=$? + set -e + if [ "$rc" -eq 0 ]; then + echo "✅ shellcheck passed" + else + echo "❌ shellcheck failed" + exit $rc + fi + + lint:yamllint: + desc: Lint YAML files with yamllint + cmds: + - | + echo "▶️ Running yamllint..." + set +e + docker run --rm -i -v "$PWD:/work" -w /work cytopia/yamllint -c .yamllint.yml . + rc=$? + set -e + if [ "$rc" -eq 0 ]; then + echo "✅ yamllint passed" + else + echo "❌ yamllint failed" + exit $rc + fi + + git:get-pr-template: + desc: Get pull request template + cmds: + - mkdir -p .tmp + - curl -LsS https://raw.githubusercontent.com/devops-infra/.github/refs/tags/v1/PULL_REQUEST_TEMPLATE.md -o .tmp/PULL_REQUEST_TEMPLATE.md + + git:set-config: + desc: Set git user config + cmds: + - git config user.name "github-actions[bot]" + - git config user.email "github-actions[bot]@users.noreply.github.com" + + scripts:dependency:update: + desc: Update Alpine apk package constraints in Dockerfile + cmds: + - | + set -eu + if [ ! -f Dockerfile ]; then + echo "ℹ️ Dockerfile 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 "ℹ️ Could not resolve base image; nothing to update" + exit 0 + fi + + case "$base_image" in + alpine:*|alpine) + : + ;; + *) + echo "ℹ️ Base image is '$base_image', not Alpine; nothing to update" + exit 0 + ;; + esac + + normalize_minor() { + version="$1" + printf '%s' "$version" | awk -F. '{print $1 "." $2}' + } + + list_file=".tmp/dependency-update-apk-list.txt" + mkdir -p .tmp + + sed -nE 's/^\s*([a-zA-Z0-9+_.-]+)=~=?([0-9]+\.[0-9]+).*$/\1 \2/p' Dockerfile > "$list_file" + if [ ! -s "$list_file" ]; then + echo "ℹ️ No pinned apk constraints (~=) found in Dockerfile" + exit 0 + fi + + updated=0 + while read -r pkg current_minor; do + [ -n "$pkg" ] || continue + latest_full="$(docker run --rm "$base_image" sh -lc "apk update >/dev/null && apk list --all '$pkg' 2>/dev/null | head -1 | awk -F'[- ]' '{print \\$2}'")" + if [ -z "$latest_full" ]; then + echo "⚠️ Could not resolve latest version for $pkg; skipping" + continue + fi + latest_minor="$(normalize_minor "$latest_full")" + if [ "$latest_minor" = "$current_minor" ]; then + echo "✅ $pkg already up to date at $current_minor" + continue + fi + echo "⬆️ $pkg: $current_minor -> $latest_minor" + {{.SED}} -i "s#\<$pkg\>=~=$current_minor#$pkg~=$latest_minor#g" Dockerfile + {{.SED}} -i "s#\<$pkg\>~=$current_minor#$pkg~=$latest_minor#g" Dockerfile + updated=1 + done < "$list_file" + + if [ "$updated" -eq 0 ]; then + echo "ℹ️ No apk dependency updates were required" + fi diff --git a/templates/actions/taskfiles/Taskfile.yml b/templates/actions/taskfiles/Taskfile.yml index 45abad0..279ab9f 100644 --- a/templates/actions/taskfiles/Taskfile.yml +++ b/templates/actions/taskfiles/Taskfile.yml @@ -7,6 +7,7 @@ dotenv: includes: variables: ./Taskfile.variables.yml + scripts: ./Taskfile.scripts.yml cicd: taskfile: ./Taskfile.cicd.yml flatten: true @@ -24,12 +25,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 diff --git a/templates/actions/workflows/auto-create-pull-request.yml b/templates/actions/workflows/auto-pull-request-create.yml similarity index 64% rename from templates/actions/workflows/auto-create-pull-request.yml rename to templates/actions/workflows/auto-pull-request-create.yml index 690ddc7..00baf22 100644 --- a/templates/actions/workflows/auto-create-pull-request.yml +++ b/templates/actions/workflows/auto-pull-request-create.yml @@ -1,4 +1,4 @@ -name: (Auto) Create Pull Request +name: (Auto) Pull Request Create on: push: @@ -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 diff --git a/templates/actions/workflows/cron-check-dependencies.yml b/templates/actions/workflows/cron-dependency-update.yml similarity index 64% rename from templates/actions/workflows/cron-check-dependencies.yml rename to templates/actions/workflows/cron-dependency-update.yml index 2aca17b..ffb07f6 100644 --- a/templates/actions/workflows/cron-check-dependencies.yml +++ b/templates/actions/workflows/cron-dependency-update.yml @@ -1,4 +1,4 @@ -name: (Cron) Check dependencies +name: (Cron) Dependency Update on: schedule: @@ -13,7 +13,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 diff --git a/templates/actions/workflows/manual-update-version.yml b/templates/actions/workflows/manual-release-create.yml similarity index 94% rename from templates/actions/workflows/manual-update-version.yml rename to templates/actions/workflows/manual-release-create.yml index 609e711..8810841 100644 --- a/templates/actions/workflows/manual-update-version.yml +++ b/templates/actions/workflows/manual-release-create.yml @@ -1,4 +1,4 @@ -name: (Manual) Update Version +name: (Manual) Release Create on: workflow_dispatch: @@ -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 }} diff --git a/templates/dockerized/taskfiles/Taskfile.cicd.yml b/templates/dockerized/taskfiles/Taskfile.cicd.yml index 9dd4008..af424b9 100644 --- a/templates/dockerized/taskfiles/Taskfile.cicd.yml +++ b/templates/dockerized/taskfiles/Taskfile.cicd.yml @@ -95,6 +95,14 @@ tasks: cmds: - echo "{{.VERSION}}" + dependency:update: + desc: Check main dependency not covered by dependabot + cmds: + - | + echo "ℹ️ No dedicated dependency updater configured for this repository profile." + echo "ℹ️ Dependabot handles GitHub Actions and package metadata updates." + echo "ℹ️ Docker builds still validate runtime dependencies during CI." + version:set: desc: Validate version cmds: diff --git a/templates/dockerized/taskfiles/Taskfile.scripts.yml b/templates/dockerized/taskfiles/Taskfile.scripts.yml index 6d9f83d..ea927c5 100644 --- a/templates/dockerized/taskfiles/Taskfile.scripts.yml +++ b/templates/dockerized/taskfiles/Taskfile.scripts.yml @@ -87,6 +87,69 @@ tasks: - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" + scripts:dependency:update: + desc: Update Alpine apk package constraints in Dockerfile + cmds: + - | + set -eu + if [ ! -f Dockerfile ]; then + echo "ℹ️ Dockerfile 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 "ℹ️ Could not resolve base image; nothing to update" + exit 0 + fi + + case "$base_image" in + alpine:*|alpine) + : + ;; + *) + echo "ℹ️ Base image is '$base_image', not Alpine; nothing to update" + exit 0 + ;; + esac + + normalize_minor() { + version="$1" + printf '%s' "$version" | awk -F. '{print $1 "." $2}' + } + + list_file=".tmp/dependency-update-apk-list.txt" + mkdir -p .tmp + + sed -nE 's/^\s*([a-zA-Z0-9+_.-]+)=~=?([0-9]+\.[0-9]+).*$/\1 \2/p' Dockerfile > "$list_file" + if [ ! -s "$list_file" ]; then + echo "ℹ️ No pinned apk constraints (~=) found in Dockerfile" + exit 0 + fi + + updated=0 + while read -r pkg current_minor; do + [ -n "$pkg" ] || continue + latest_full="$(docker run --rm "$base_image" sh -lc "apk update >/dev/null && apk list --all '$pkg' 2>/dev/null | head -1 | awk -F'[- ]' '{print \\$2}'")" + if [ -z "$latest_full" ]; then + echo "⚠️ Could not resolve latest version for $pkg; skipping" + continue + fi + latest_minor="$(normalize_minor "$latest_full")" + if [ "$latest_minor" = "$current_minor" ]; then + echo "✅ $pkg already up to date at $current_minor" + continue + fi + echo "⬆️ $pkg: $current_minor -> $latest_minor" + {{.SED}} -i "s#\<$pkg\>=~=$current_minor#$pkg~=$latest_minor#g" Dockerfile + {{.SED}} -i "s#\<$pkg\>~=$current_minor#$pkg~=$latest_minor#g" Dockerfile + updated=1 + done < "$list_file" + + if [ "$updated" -eq 0 ]; then + echo "ℹ️ No apk dependency updates were required" + fi + version:get: desc: Get current version cmds: diff --git a/templates/dockerized/workflows/auto-create-pull-request.yml b/templates/dockerized/workflows/auto-pull-request-create.yml similarity index 64% rename from templates/dockerized/workflows/auto-create-pull-request.yml rename to templates/dockerized/workflows/auto-pull-request-create.yml index 8102c39..8bd37f8 100644 --- a/templates/dockerized/workflows/auto-create-pull-request.yml +++ b/templates/dockerized/workflows/auto-pull-request-create.yml @@ -1,4 +1,4 @@ -name: (Auto) Create Pull Request +name: (Auto) Pull Request Create on: push: @@ -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: dockerized secrets: inherit diff --git a/templates/dockerized/workflows/cron-check-dependencies.yml b/templates/dockerized/workflows/cron-dependency-update.yml similarity index 64% rename from templates/dockerized/workflows/cron-check-dependencies.yml rename to templates/dockerized/workflows/cron-dependency-update.yml index 62dd5c2..03c8ee8 100644 --- a/templates/dockerized/workflows/cron-check-dependencies.yml +++ b/templates/dockerized/workflows/cron-dependency-update.yml @@ -1,4 +1,4 @@ -name: (Cron) Check dependencies +name: (Cron) Dependency Update on: schedule: @@ -13,7 +13,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: dockerized secrets: inherit diff --git a/templates/dockerized/workflows/manual-update-version.yml b/templates/dockerized/workflows/manual-release-create.yml similarity index 94% rename from templates/dockerized/workflows/manual-update-version.yml rename to templates/dockerized/workflows/manual-release-create.yml index 8d43eea..627d2a9 100644 --- a/templates/dockerized/workflows/manual-update-version.yml +++ b/templates/dockerized/workflows/manual-release-create.yml @@ -1,4 +1,4 @@ -name: (Manual) Update Version +name: (Manual) Release Create on: workflow_dispatch: @@ -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 }} diff --git a/templates/other/taskfiles/Taskfile.cicd.yml b/templates/other/taskfiles/Taskfile.cicd.yml index 03319e0..08e3794 100644 --- a/templates/other/taskfiles/Taskfile.cicd.yml +++ b/templates/other/taskfiles/Taskfile.cicd.yml @@ -90,6 +90,14 @@ tasks: cmds: - echo "{{.VERSION}}" + dependency:update: + desc: Check main dependency not covered by dependabot + cmds: + - | + echo "ℹ️ No dedicated dependency updater configured for this repository profile." + echo "ℹ️ Dependabot handles GitHub Actions and package metadata updates." + echo "ℹ️ Keep this task as a safe no-op until a repo-specific dependency updater is defined." + version:set: desc: Validate version cmds: diff --git a/templates/other/workflows/auto-create-pull-request.yml b/templates/other/workflows/auto-pull-request-create.yml similarity index 64% rename from templates/other/workflows/auto-create-pull-request.yml rename to templates/other/workflows/auto-pull-request-create.yml index 812578a..a5fbedd 100644 --- a/templates/other/workflows/auto-create-pull-request.yml +++ b/templates/other/workflows/auto-pull-request-create.yml @@ -1,4 +1,4 @@ -name: (Auto) Create Pull Request +name: (Auto) Pull Request Create on: push: @@ -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: other secrets: inherit diff --git a/templates/other/workflows/cron-check-dependencies.yml b/templates/other/workflows/cron-dependency-update.yml similarity index 63% rename from templates/other/workflows/cron-check-dependencies.yml rename to templates/other/workflows/cron-dependency-update.yml index c4614d3..e87f53c 100644 --- a/templates/other/workflows/cron-check-dependencies.yml +++ b/templates/other/workflows/cron-dependency-update.yml @@ -1,4 +1,4 @@ -name: (Cron) Check dependencies +name: (Cron) Dependency Update on: schedule: @@ -13,7 +13,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: other secrets: inherit diff --git a/templates/other/workflows/manual-update-version.yml b/templates/other/workflows/manual-release-create.yml similarity index 94% rename from templates/other/workflows/manual-update-version.yml rename to templates/other/workflows/manual-release-create.yml index 7b89f00..fbb2fa5 100644 --- a/templates/other/workflows/manual-update-version.yml +++ b/templates/other/workflows/manual-release-create.yml @@ -1,4 +1,4 @@ -name: (Manual) Update Version +name: (Manual) Release Create on: workflow_dispatch: @@ -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 }} diff --git a/templates/static/taskfiles/Taskfile.cicd.yml b/templates/static/taskfiles/Taskfile.cicd.yml index b217034..577491c 100644 --- a/templates/static/taskfiles/Taskfile.cicd.yml +++ b/templates/static/taskfiles/Taskfile.cicd.yml @@ -45,6 +45,14 @@ tasks: cmds: - task scripts:version:get + dependency:update: + desc: Check main dependency not covered by dependabot + cmds: + - | + echo "ℹ️ No dedicated dependency updater configured for this repository profile." + echo "ℹ️ Dependabot handles GitHub Actions and package metadata updates." + echo "ℹ️ Keep this task as a safe no-op until a repo-specific dependency updater is defined." + version:set: desc: Validate version cmds: diff --git a/templates/static/workflows/auto-create-pull-request.yml b/templates/static/workflows/auto-pull-request-create.yml similarity index 64% rename from templates/static/workflows/auto-create-pull-request.yml rename to templates/static/workflows/auto-pull-request-create.yml index 0371481..32482d2 100644 --- a/templates/static/workflows/auto-create-pull-request.yml +++ b/templates/static/workflows/auto-pull-request-create.yml @@ -1,4 +1,4 @@ -name: (Auto) Create Pull Request +name: (Auto) Pull Request Create on: push: @@ -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: static secrets: inherit diff --git a/templates/static/workflows/cron-check-dependencies.yml b/templates/static/workflows/cron-dependency-update.yml similarity index 64% rename from templates/static/workflows/cron-check-dependencies.yml rename to templates/static/workflows/cron-dependency-update.yml index e3c5fff..07f1eaa 100644 --- a/templates/static/workflows/cron-check-dependencies.yml +++ b/templates/static/workflows/cron-dependency-update.yml @@ -1,4 +1,4 @@ -name: (Cron) Check dependencies +name: (Cron) Dependency Update on: schedule: @@ -13,7 +13,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: static secrets: inherit diff --git a/templates/static/workflows/manual-update-version.yml b/templates/static/workflows/manual-release-create.yml similarity index 94% rename from templates/static/workflows/manual-update-version.yml rename to templates/static/workflows/manual-release-create.yml index 42d2c97..774c669 100644 --- a/templates/static/workflows/manual-update-version.yml +++ b/templates/static/workflows/manual-release-create.yml @@ -1,4 +1,4 @@ -name: (Manual) Update Version +name: (Manual) Release Create on: workflow_dispatch: @@ -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 }} From 6f0bba4cb8a1f9fed4e81d32a324423690e13de2 Mon Sep 17 00:00:00 2001 From: ChristophShyper <45788587+ChristophShyper@users.noreply.github.com> Date: Wed, 15 Apr 2026 23:16:27 +0200 Subject: [PATCH 2/3] feat: add support for Alpine packages updates --- .../reusable-auto-pull-request-create.yml | 10 +- .../reusable-cron-dependency-update.yml | 10 +- .../reusable-manual-release-create.yml | 10 +- Taskfile.cicd.yml | 46 +----- Taskfile.yml | 1 - templates/actions/configs/.dockerignore | 1 + templates/actions/configs/alpine-packages.txt | 1 + templates/actions/taskfiles/Taskfile.cicd.yml | 48 +------ .../actions/taskfiles/Taskfile.docker.yml | 133 ------------------ .../actions/taskfiles/Taskfile.scripts.yml | 108 +++++++++++--- templates/actions/taskfiles/Taskfile.yml | 1 - templates/dockerized/configs/.dockerignore | 1 + .../dockerized/configs/alpine-packages.txt | 1 + .../dockerized/taskfiles/Taskfile.cicd.yml | 49 +------ .../dockerized/taskfiles/Taskfile.docker.yml | 133 ------------------ .../dockerized/taskfiles/Taskfile.scripts.yml | 108 +++++++++++--- templates/other/taskfiles/Taskfile.cicd.yml | 46 +----- templates/static/taskfiles/Taskfile.cicd.yml | 43 +----- 18 files changed, 204 insertions(+), 546 deletions(-) create mode 100644 templates/actions/configs/alpine-packages.txt create mode 100644 templates/dockerized/configs/alpine-packages.txt diff --git a/.github/workflows/reusable-auto-pull-request-create.yml b/.github/workflows/reusable-auto-pull-request-create.yml index 81b5caf..b1e5a22 100644 --- a/.github/workflows/reusable-auto-pull-request-create.yml +++ b/.github/workflows/reusable-auto-pull-request-create.yml @@ -138,16 +138,12 @@ jobs: echo "EOF" } >> "$GITHUB_OUTPUT" - - name: Resolve CST image + - name: Get test image ref id: cst-image if: steps.cst-configs.outputs.has_tests == 'true' run: | - if task --list | grep -q "docker:image:test:ref"; then - IMAGE_REF="$(task docker:image:test:ref)" - else - VERSION="$(task version:get)" - IMAGE_REF="devopsinfra/${{ github.event.repository.name }}:${VERSION}-test" - fi + VERSION="$(task version:get)" + IMAGE_REF="devopsinfra/${{ github.event.repository.name }}:${VERSION}-test" echo "image=$IMAGE_REF" >> "$GITHUB_OUTPUT" - name: Run container structure tests diff --git a/.github/workflows/reusable-cron-dependency-update.yml b/.github/workflows/reusable-cron-dependency-update.yml index 22d6f96..c744006 100644 --- a/.github/workflows/reusable-cron-dependency-update.yml +++ b/.github/workflows/reusable-cron-dependency-update.yml @@ -145,17 +145,13 @@ jobs: echo "EOF" } >> "$GITHUB_OUTPUT" - - name: Resolve CST image + - name: Get test image ref id: cst-image if: (inputs.profile == 'actions' || inputs.profile == 'dockerized') && steps.cst-configs.outputs.has_tests == 'true' continue-on-error: true run: | - if task --list | grep -q "docker:image:test:ref"; then - IMAGE_REF="$(task docker:image:test:ref)" - else - VERSION="$(task version:get)" - IMAGE_REF="devopsinfra/${{ github.event.repository.name }}:${VERSION}-test" - fi + VERSION="$(task version:get)" + IMAGE_REF="devopsinfra/${{ github.event.repository.name }}:${VERSION}-test" echo "image=$IMAGE_REF" >> "$GITHUB_OUTPUT" - name: Run container structure tests diff --git a/.github/workflows/reusable-manual-release-create.yml b/.github/workflows/reusable-manual-release-create.yml index 83727fe..7a2e9f6 100644 --- a/.github/workflows/reusable-manual-release-create.yml +++ b/.github/workflows/reusable-manual-release-create.yml @@ -119,18 +119,14 @@ jobs: echo "EOF" } >> "$GITHUB_OUTPUT" - - name: Resolve CST image + - name: Get test image ref id: cst-image if: ${{ inputs.build-and-push-only && (inputs.profile == 'actions' || inputs.profile == 'dockerized') && steps.cst-configs.outputs.has_tests == 'true' }} env: VERSION_SUFFIX: '' run: | - if task --list | grep -q "docker:image:test:ref"; then - IMAGE_REF="$(task docker:image:test:ref)" - else - VERSION="$(task version:get)" - IMAGE_REF="devopsinfra/${{ github.event.repository.name }}:${VERSION}" - fi + VERSION="$(task version:get)" + IMAGE_REF="devopsinfra/${{ github.event.repository.name }}:${VERSION}" echo "image=$IMAGE_REF" >> "$GITHUB_OUTPUT" - name: Run container structure tests diff --git a/Taskfile.cicd.yml b/Taskfile.cicd.yml index 26a6e1b..f21bc3f 100644 --- a/Taskfile.cicd.yml +++ b/Taskfile.cicd.yml @@ -110,11 +110,6 @@ tasks: exit $rc fi - version:get: - desc: Get current version - cmds: - - echo "{{.VERSION}}" - dependency:update: desc: Check main dependency not covered by dependabot cmds: @@ -281,42 +276,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}}/.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 .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 - git add .gitignore - 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.scripts.yml -o ./Taskfile.scripts.yml - curl -fsSL {{.TASKFILES_BASE_URL}}/Taskfile.variables.yml -o ./Taskfile.variables.yml - git add Taskfile*.yml - echo "✅ Synced Taskfiles" + - echo "{{.VERSION}}" diff --git a/Taskfile.yml b/Taskfile.yml index d3428d8..fa10a3a 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -11,7 +11,6 @@ includes: taskfile: ./Taskfile.cicd.yml flatten: true - tasks: default: desc: List tasks diff --git a/templates/actions/configs/.dockerignore b/templates/actions/configs/.dockerignore index ef1376f..1bc823c 100644 --- a/templates/actions/configs/.dockerignore +++ b/templates/actions/configs/.dockerignore @@ -2,6 +2,7 @@ * # Include +!alpine-packages.txt !Dockerfile !LICENSE !README.md diff --git a/templates/actions/configs/alpine-packages.txt b/templates/actions/configs/alpine-packages.txt new file mode 100644 index 0000000..5137600 --- /dev/null +++ b/templates/actions/configs/alpine-packages.txt @@ -0,0 +1 @@ +bash~=5.3 diff --git a/templates/actions/taskfiles/Taskfile.cicd.yml b/templates/actions/taskfiles/Taskfile.cicd.yml index 17a702b..9b8ca64 100644 --- a/templates/actions/taskfiles/Taskfile.cicd.yml +++ b/templates/actions/taskfiles/Taskfile.cicd.yml @@ -90,11 +90,6 @@ tasks: exit $rc fi - version:get: - desc: Get current version - cmds: - - echo "{{.VERSION}}" - dependency:update: desc: Check main dependency not covered by dependabot cmds: @@ -272,44 +267,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}}" diff --git a/templates/actions/taskfiles/Taskfile.docker.yml b/templates/actions/taskfiles/Taskfile.docker.yml index a05bc36..323a64d 100644 --- a/templates/actions/taskfiles/Taskfile.docker.yml +++ b/templates/actions/taskfiles/Taskfile.docker.yml @@ -3,136 +3,3 @@ version: '3' silent: true tasks: - docker:image:test:ref: - desc: Print test image reference for CST - cmds: - - echo "{{.DOCKER_NAME}}:{{.VERSION_FULL}}{{.VERSION_SUFFIX}}" - - docker:login: - desc: Login to hub.docker.com and ghcr.io - cmds: - - | - set -eu - docker_username='{{.DOCKER_USERNAME}}' - github_username='{{.GITHUB_USERNAME}}' - has_dockerhub=false - has_ghcr=false - - if [ -n "$docker_username" ] && [ -n "${DOCKER_TOKEN:-}" ]; then - has_dockerhub=true - fi - - if [ -n "$github_username" ] && [ -n "${GITHUB_TOKEN:-}" ]; then - has_ghcr=true - fi - - if [ "$has_dockerhub" = false ] && [ "$has_ghcr" = false ]; then - echo "❌ No registry credentials provided. Set DOCKER_USERNAME/DOCKER_TOKEN or GITHUB_USERNAME/GITHUB_TOKEN." - exit 1 - fi - - if [ "$has_dockerhub" = true ]; then - echo "Logging into Docker Hub as $docker_username" - printf '%s' "${DOCKER_TOKEN}" | docker login -u "$docker_username" --password-stdin - else - echo "⚠️ Skipping Docker Hub login (missing DOCKER_USERNAME/DOCKER_TOKEN)" - fi - - if [ "$has_ghcr" = true ]; then - echo "Logging into GHCR as $github_username" - printf '%s' "${GITHUB_TOKEN}" | docker login ghcr.io -u "$github_username" --password-stdin - else - echo "⚠️ Skipping GHCR login (missing GITHUB_USERNAME/GITHUB_TOKEN)" - fi - - docker:cmds: - desc: Show full docker build command - cmds: - - echo -e '{{.DOCKER_BUILD_START}} {{.DOCKER_BUILD_FINISH}}' | {{.SED}} 's/--/ \\\n --/g' - - docker:build: - desc: Build Docker image - cmds: - - docker buildx create --use - - '{{.DOCKER_BUILD_START}} {{.DOCKER_BUILD_FINISH}}' - - docker:build:inspect: - desc: Inspect built Docker image - cmds: - - | - image_inspect_out=$(docker image inspect {{.DOCKER_NAME}}:{{.VERSION_FULL}}{{.VERSION_SUFFIX}} | jq -r) - echo -e "\nℹ️ Docker image inspect:" - echo "$image_inspect_out" | jq - - docker:push: - desc: Build and push Docker images - deps: - - task: docker:login - cmds: - - docker buildx create --use - - '{{.DOCKER_BUILD_START}} --push {{.DOCKER_BUILD_FINISH}}' - - docker:push:inspect: - desc: Inspect built Docker image - cmds: - - | - set -eu - image="{{.DOCKER_NAME}}:{{.VERSION_FULL}}{{.VERSION_SUFFIX}}" - - echo -e "\nℹ️ Trying local image inspect: $image" - set +e - image_inspect_out=$(docker image inspect "$image" 2>/dev/null || true) - rc=$? - set -e - - # Validate that docker inspect returned a non-empty array with an Id - has_local=0 - if [ "$rc" -eq 0 ] && [ -n "$image_inspect_out" ]; then - if echo "$image_inspect_out" | jq -e 'type=="array" and (length > 0) and \ - (.[0].Id != null and .[0].Id != "")' >/dev/null 2>&1; then - has_local=1 - fi - fi - - if [ "$has_local" -eq 1 ]; then - echo -e "\n✅ Local image found. Docker image inspect:" - echo "$image_inspect_out" | jq - image_sha=$(echo "$image_inspect_out" | jq -r '.[0].Id // empty') - if [ -n "$image_sha" ]; then - echo -e "\nℹ️ Docker manifest inspect (local):" - docker manifest inspect "${image}@${image_sha}" | jq || true - fi - exit 0 - fi - - echo -e "\nℹ️ Local image not found or inspect returned empty; inspecting remote with buildx imagetools..." - set +e - raw=$(docker buildx imagetools inspect --raw "$image" 2>/dev/null || true) - set -e - - if [ -z "$raw" ]; then - echo "❌ Failed to inspect remote image with buildx imagetools: $image" - exit 1 - fi - - echo -e "\n✅ Remote manifest/index (raw):" - echo "$raw" | jq - - echo -e "\nℹ️ Attempting to pull and inspect per-platform manifests:" - echo "$raw" | jq -r '.manifests[]?.digest' | while IFS= read -r digest; do - if [ -z "$digest" ] || [ "$digest" = "null" ]; then - continue - fi - ref="${image%@*}@${digest}" - echo -e "\nℹ️ Pulling $ref (may fail for some registries)..." - set +e - docker pull "$ref" >/dev/null 2>&1 || true - pulled_rc=$? - set -e - if [ "$pulled_rc" -eq 0 ]; then - echo "ℹ️ Inspecting pulled image $ref" - docker image inspect "$ref" | jq || true - else - echo "⚠️ Could not pull $ref; skipping image inspect" - fi - done diff --git a/templates/actions/taskfiles/Taskfile.scripts.yml b/templates/actions/taskfiles/Taskfile.scripts.yml index 3a24938..3c405b3 100644 --- a/templates/actions/taskfiles/Taskfile.scripts.yml +++ b/templates/actions/taskfiles/Taskfile.scripts.yml @@ -86,19 +86,23 @@ tasks: - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - scripts:dependency:update: - desc: Update Alpine apk package constraints in Dockerfile + packages:update: + desc: Update Alpine package pins in alpine-packages.txt cmds: - | set -eu if [ ! -f Dockerfile ]; then - echo "ℹ️ Dockerfile not found; nothing to update" + 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 "ℹ️ Could not resolve base image; nothing to update" + echo "INFO: Could not resolve base image; nothing to update" exit 0 fi @@ -107,44 +111,108 @@ tasks: : ;; *) - echo "ℹ️ Base image is '$base_image', not Alpine; nothing to update" + 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" | awk -F. '{print $1 "." $2}' + 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 } - list_file=".tmp/dependency-update-apk-list.txt" 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" - sed -nE 's/^\s*([a-zA-Z0-9+_.-]+)=~=?([0-9]+\.[0-9]+).*$/\1 \2/p' Dockerfile > "$list_file" - if [ ! -s "$list_file" ]; then - echo "ℹ️ No pinned apk constraints (~=) found in Dockerfile" + 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 read -r pkg current_minor; do - [ -n "$pkg" ] || continue - latest_full="$(docker run --rm "$base_image" sh -lc "apk update >/dev/null && apk list --all '$pkg' 2>/dev/null | head -1 | awk -F'[- ]' '{print \\$2}'")" + 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 "⚠️ Could not resolve latest version for $pkg; skipping" + 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 "✅ $pkg already up to date at $current_minor" + echo "OK: $pkg already up to date at $current_minor" + echo "$pkg~=$current_minor" >> "$tmp_out" continue fi - echo "⬆️ $pkg: $current_minor -> $latest_minor" - {{.SED}} -i "s#\<$pkg\>=~=$current_minor#$pkg~=$latest_minor#g" Dockerfile - {{.SED}} -i "s#\<$pkg\>~=$current_minor#$pkg~=$latest_minor#g" Dockerfile + echo "UPDATE: $pkg $current_minor -> $latest_minor" + echo "$pkg~=$latest_minor" >> "$tmp_out" updated=1 - done < "$list_file" + 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 "ℹ️ No apk dependency updates were required" + echo "INFO: No Alpine package updates were required" fi diff --git a/templates/actions/taskfiles/Taskfile.yml b/templates/actions/taskfiles/Taskfile.yml index 279ab9f..a065cbc 100644 --- a/templates/actions/taskfiles/Taskfile.yml +++ b/templates/actions/taskfiles/Taskfile.yml @@ -15,7 +15,6 @@ includes: taskfile: ./Taskfile.docker.yml flatten: true - tasks: default: desc: List tasks diff --git a/templates/dockerized/configs/.dockerignore b/templates/dockerized/configs/.dockerignore index ef1376f..1bc823c 100644 --- a/templates/dockerized/configs/.dockerignore +++ b/templates/dockerized/configs/.dockerignore @@ -2,6 +2,7 @@ * # Include +!alpine-packages.txt !Dockerfile !LICENSE !README.md diff --git a/templates/dockerized/configs/alpine-packages.txt b/templates/dockerized/configs/alpine-packages.txt new file mode 100644 index 0000000..5137600 --- /dev/null +++ b/templates/dockerized/configs/alpine-packages.txt @@ -0,0 +1 @@ +bash~=5.3 diff --git a/templates/dockerized/taskfiles/Taskfile.cicd.yml b/templates/dockerized/taskfiles/Taskfile.cicd.yml index af424b9..aee3248 100644 --- a/templates/dockerized/taskfiles/Taskfile.cicd.yml +++ b/templates/dockerized/taskfiles/Taskfile.cicd.yml @@ -90,11 +90,6 @@ tasks: exit $rc fi - version:get: - desc: Get current version - cmds: - - echo "{{.VERSION}}" - dependency:update: desc: Check main dependency not covered by dependabot cmds: @@ -261,45 +256,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.scripts.yml -o ./Taskfile.scripts.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}}" diff --git a/templates/dockerized/taskfiles/Taskfile.docker.yml b/templates/dockerized/taskfiles/Taskfile.docker.yml index a05bc36..323a64d 100644 --- a/templates/dockerized/taskfiles/Taskfile.docker.yml +++ b/templates/dockerized/taskfiles/Taskfile.docker.yml @@ -3,136 +3,3 @@ version: '3' silent: true tasks: - docker:image:test:ref: - desc: Print test image reference for CST - cmds: - - echo "{{.DOCKER_NAME}}:{{.VERSION_FULL}}{{.VERSION_SUFFIX}}" - - docker:login: - desc: Login to hub.docker.com and ghcr.io - cmds: - - | - set -eu - docker_username='{{.DOCKER_USERNAME}}' - github_username='{{.GITHUB_USERNAME}}' - has_dockerhub=false - has_ghcr=false - - if [ -n "$docker_username" ] && [ -n "${DOCKER_TOKEN:-}" ]; then - has_dockerhub=true - fi - - if [ -n "$github_username" ] && [ -n "${GITHUB_TOKEN:-}" ]; then - has_ghcr=true - fi - - if [ "$has_dockerhub" = false ] && [ "$has_ghcr" = false ]; then - echo "❌ No registry credentials provided. Set DOCKER_USERNAME/DOCKER_TOKEN or GITHUB_USERNAME/GITHUB_TOKEN." - exit 1 - fi - - if [ "$has_dockerhub" = true ]; then - echo "Logging into Docker Hub as $docker_username" - printf '%s' "${DOCKER_TOKEN}" | docker login -u "$docker_username" --password-stdin - else - echo "⚠️ Skipping Docker Hub login (missing DOCKER_USERNAME/DOCKER_TOKEN)" - fi - - if [ "$has_ghcr" = true ]; then - echo "Logging into GHCR as $github_username" - printf '%s' "${GITHUB_TOKEN}" | docker login ghcr.io -u "$github_username" --password-stdin - else - echo "⚠️ Skipping GHCR login (missing GITHUB_USERNAME/GITHUB_TOKEN)" - fi - - docker:cmds: - desc: Show full docker build command - cmds: - - echo -e '{{.DOCKER_BUILD_START}} {{.DOCKER_BUILD_FINISH}}' | {{.SED}} 's/--/ \\\n --/g' - - docker:build: - desc: Build Docker image - cmds: - - docker buildx create --use - - '{{.DOCKER_BUILD_START}} {{.DOCKER_BUILD_FINISH}}' - - docker:build:inspect: - desc: Inspect built Docker image - cmds: - - | - image_inspect_out=$(docker image inspect {{.DOCKER_NAME}}:{{.VERSION_FULL}}{{.VERSION_SUFFIX}} | jq -r) - echo -e "\nℹ️ Docker image inspect:" - echo "$image_inspect_out" | jq - - docker:push: - desc: Build and push Docker images - deps: - - task: docker:login - cmds: - - docker buildx create --use - - '{{.DOCKER_BUILD_START}} --push {{.DOCKER_BUILD_FINISH}}' - - docker:push:inspect: - desc: Inspect built Docker image - cmds: - - | - set -eu - image="{{.DOCKER_NAME}}:{{.VERSION_FULL}}{{.VERSION_SUFFIX}}" - - echo -e "\nℹ️ Trying local image inspect: $image" - set +e - image_inspect_out=$(docker image inspect "$image" 2>/dev/null || true) - rc=$? - set -e - - # Validate that docker inspect returned a non-empty array with an Id - has_local=0 - if [ "$rc" -eq 0 ] && [ -n "$image_inspect_out" ]; then - if echo "$image_inspect_out" | jq -e 'type=="array" and (length > 0) and \ - (.[0].Id != null and .[0].Id != "")' >/dev/null 2>&1; then - has_local=1 - fi - fi - - if [ "$has_local" -eq 1 ]; then - echo -e "\n✅ Local image found. Docker image inspect:" - echo "$image_inspect_out" | jq - image_sha=$(echo "$image_inspect_out" | jq -r '.[0].Id // empty') - if [ -n "$image_sha" ]; then - echo -e "\nℹ️ Docker manifest inspect (local):" - docker manifest inspect "${image}@${image_sha}" | jq || true - fi - exit 0 - fi - - echo -e "\nℹ️ Local image not found or inspect returned empty; inspecting remote with buildx imagetools..." - set +e - raw=$(docker buildx imagetools inspect --raw "$image" 2>/dev/null || true) - set -e - - if [ -z "$raw" ]; then - echo "❌ Failed to inspect remote image with buildx imagetools: $image" - exit 1 - fi - - echo -e "\n✅ Remote manifest/index (raw):" - echo "$raw" | jq - - echo -e "\nℹ️ Attempting to pull and inspect per-platform manifests:" - echo "$raw" | jq -r '.manifests[]?.digest' | while IFS= read -r digest; do - if [ -z "$digest" ] || [ "$digest" = "null" ]; then - continue - fi - ref="${image%@*}@${digest}" - echo -e "\nℹ️ Pulling $ref (may fail for some registries)..." - set +e - docker pull "$ref" >/dev/null 2>&1 || true - pulled_rc=$? - set -e - if [ "$pulled_rc" -eq 0 ]; then - echo "ℹ️ Inspecting pulled image $ref" - docker image inspect "$ref" | jq || true - else - echo "⚠️ Could not pull $ref; skipping image inspect" - fi - done diff --git a/templates/dockerized/taskfiles/Taskfile.scripts.yml b/templates/dockerized/taskfiles/Taskfile.scripts.yml index ea927c5..21e4e63 100644 --- a/templates/dockerized/taskfiles/Taskfile.scripts.yml +++ b/templates/dockerized/taskfiles/Taskfile.scripts.yml @@ -87,19 +87,23 @@ tasks: - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - scripts:dependency:update: - desc: Update Alpine apk package constraints in Dockerfile + packages:update: + desc: Update Alpine package pins in alpine-packages.txt cmds: - | set -eu if [ ! -f Dockerfile ]; then - echo "ℹ️ Dockerfile not found; nothing to update" + 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 "ℹ️ Could not resolve base image; nothing to update" + echo "INFO: Could not resolve base image; nothing to update" exit 0 fi @@ -108,46 +112,110 @@ tasks: : ;; *) - echo "ℹ️ Base image is '$base_image', not Alpine; nothing to update" + 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" | awk -F. '{print $1 "." $2}' + 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 } - list_file=".tmp/dependency-update-apk-list.txt" 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" - sed -nE 's/^\s*([a-zA-Z0-9+_.-]+)=~=?([0-9]+\.[0-9]+).*$/\1 \2/p' Dockerfile > "$list_file" - if [ ! -s "$list_file" ]; then - echo "ℹ️ No pinned apk constraints (~=) found in Dockerfile" + 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 read -r pkg current_minor; do - [ -n "$pkg" ] || continue - latest_full="$(docker run --rm "$base_image" sh -lc "apk update >/dev/null && apk list --all '$pkg' 2>/dev/null | head -1 | awk -F'[- ]' '{print \\$2}'")" + 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 "⚠️ Could not resolve latest version for $pkg; skipping" + 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 "✅ $pkg already up to date at $current_minor" + echo "OK: $pkg already up to date at $current_minor" + echo "$pkg~=$current_minor" >> "$tmp_out" continue fi - echo "⬆️ $pkg: $current_minor -> $latest_minor" - {{.SED}} -i "s#\<$pkg\>=~=$current_minor#$pkg~=$latest_minor#g" Dockerfile - {{.SED}} -i "s#\<$pkg\>~=$current_minor#$pkg~=$latest_minor#g" Dockerfile + echo "UPDATE: $pkg $current_minor -> $latest_minor" + echo "$pkg~=$latest_minor" >> "$tmp_out" updated=1 - done < "$list_file" + 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 "ℹ️ No apk dependency updates were required" + echo "INFO: No Alpine package updates were required" fi version:get: diff --git a/templates/other/taskfiles/Taskfile.cicd.yml b/templates/other/taskfiles/Taskfile.cicd.yml index 08e3794..05c86cb 100644 --- a/templates/other/taskfiles/Taskfile.cicd.yml +++ b/templates/other/taskfiles/Taskfile.cicd.yml @@ -85,11 +85,6 @@ tasks: exit $rc fi - version:get: - desc: Get current version - cmds: - - echo "{{.VERSION}}" - dependency:update: desc: Check main dependency not covered by dependabot cmds: @@ -256,42 +251,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}}/.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 .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 - git add .gitignore - 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.scripts.yml -o ./Taskfile.scripts.yml - curl -fsSL {{.TASKFILES_BASE_URL}}/Taskfile.variables.yml -o ./Taskfile.variables.yml - git add Taskfile*.yml - echo "✅ Synced Taskfiles" + - echo "{{.VERSION}}" diff --git a/templates/static/taskfiles/Taskfile.cicd.yml b/templates/static/taskfiles/Taskfile.cicd.yml index 577491c..5233735 100644 --- a/templates/static/taskfiles/Taskfile.cicd.yml +++ b/templates/static/taskfiles/Taskfile.cicd.yml @@ -40,11 +40,6 @@ tasks: cmds: - task scripts:lint:yamllint - version:get: - desc: Get current version - cmds: - - task scripts:version:get - dependency:update: desc: Check main dependency not covered by dependabot cmds: @@ -135,39 +130,7 @@ tasks: cmds: - task scripts:git:set-config - sync:all: - desc: Sync all common files - cmds: - - task sync:configs - - task sync:ignores - - task sync:taskfiles - - sync:configs: - desc: Sync configuration files from .github static template - cmds: - - | - echo "Syncing configuration files from devops-infra/.github..." - curl -fsSL {{.CONFIGS_BASE_URL}}/.editorconfig -o ./.editorconfig - 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 .pre-commit-config.yaml .shellcheckrc .yamllint.yml - - sync:ignores: - desc: Sync ignore files from .github static template - cmds: - - | - echo "Syncing ignore files from devops-infra/.github..." - curl -fsSL {{.CONFIGS_BASE_URL}}/.gitignore -o ./.gitignore - git add .gitignore - - sync:taskfiles: - desc: Sync Taskfiles from .github static template + 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.variables.yml -o ./Taskfile.variables.yml - curl -fsSL {{.TASKFILES_BASE_URL}}/Taskfile.scripts.yml -o ./Taskfile.scripts.yml - git add Taskfile*.yml + - task scripts:version:get From dab87f5a2249f642016e3a45aef864cf405eeba0 Mon Sep 17 00:00:00 2001 From: ChristophShyper <45788587+ChristophShyper@users.noreply.github.com> Date: Wed, 15 Apr 2026 23:23:04 +0200 Subject: [PATCH 3/3] fix: restore Taskfile.docker.yml --- .../actions/taskfiles/Taskfile.docker.yml | 127 ++++++++++++++++++ .../dockerized/taskfiles/Taskfile.docker.yml | 127 ++++++++++++++++++ 2 files changed, 254 insertions(+) diff --git a/templates/actions/taskfiles/Taskfile.docker.yml b/templates/actions/taskfiles/Taskfile.docker.yml index 323a64d..f0f0baa 100644 --- a/templates/actions/taskfiles/Taskfile.docker.yml +++ b/templates/actions/taskfiles/Taskfile.docker.yml @@ -3,3 +3,130 @@ version: '3' silent: true tasks: + docker:login: + desc: Login to hub.docker.com and ghcr.io + cmds: + - | + set -eu + docker_username='{{.DOCKER_USERNAME}}' + github_username='{{.GITHUB_USERNAME}}' + has_dockerhub=false + has_ghcr=false + + if [ -n "$docker_username" ] && [ -n "${DOCKER_TOKEN:-}" ]; then + has_dockerhub=true + fi + + if [ -n "$github_username" ] && [ -n "${GITHUB_TOKEN:-}" ]; then + has_ghcr=true + fi + + if [ "$has_dockerhub" = false ] && [ "$has_ghcr" = false ]; then + echo "❌ No registry credentials provided. Set DOCKER_USERNAME/DOCKER_TOKEN or GITHUB_USERNAME/GITHUB_TOKEN." + exit 1 + fi + + if [ "$has_dockerhub" = true ]; then + echo "Logging into Docker Hub as $docker_username" + printf '%s' "${DOCKER_TOKEN}" | docker login -u "$docker_username" --password-stdin + else + echo "⚠️ Skipping Docker Hub login (missing DOCKER_USERNAME/DOCKER_TOKEN)" + fi + + if [ "$has_ghcr" = true ]; then + echo "Logging into GHCR as $github_username" + printf '%s' "${GITHUB_TOKEN}" | docker login ghcr.io -u "$github_username" --password-stdin + else + echo "⚠️ Skipping GHCR login (missing GITHUB_USERNAME/GITHUB_TOKEN)" + fi + + docker:cmds: + desc: Show full docker build command + cmds: + - echo -e '{{.DOCKER_BUILD_START}} {{.DOCKER_BUILD_FINISH}}' | {{.SED}} 's/--/ \\\n+ --/g' + + docker:build: + desc: Build Docker image + cmds: + - docker buildx create --use + - '{{.DOCKER_BUILD_START}} {{.DOCKER_BUILD_FINISH}}' + + docker:build:inspect: + desc: Inspect built Docker image + cmds: + - | + image_inspect_out=$(docker image inspect {{.DOCKER_NAME}}:{{.VERSION_FULL}}{{.VERSION_SUFFIX}} | jq -r) + echo -e "\nℹ️ Docker image inspect:" + echo "$image_inspect_out" | jq + + docker:push: + desc: Build and push Docker images + deps: + - task: docker:login + cmds: + - docker buildx create --use + - '{{.DOCKER_BUILD_START}} --push {{.DOCKER_BUILD_FINISH}}' + + docker:push:inspect: + desc: Inspect built Docker image + cmds: + - | + set -eu + image="{{.DOCKER_NAME}}:{{.VERSION_FULL}}{{.VERSION_SUFFIX}}" + + echo -e "\nℹ️ Trying local image inspect: $image" + set +e + image_inspect_out=$(docker image inspect "$image" 2>/dev/null || true) + rc=$? + set -e + + has_local=0 + if [ "$rc" -eq 0 ] && [ -n "$image_inspect_out" ]; then + if echo "$image_inspect_out" | jq -e 'type=="array" and (length > 0) and \ + (.[0].Id != null and .[0].Id != "")' >/dev/null 2>&1; then + has_local=1 + fi + fi + + if [ "$has_local" -eq 1 ]; then + echo -e "\n✅ Local image found. Docker image inspect:" + echo "$image_inspect_out" | jq + image_sha=$(echo "$image_inspect_out" | jq -r '.[0].Id // empty') + if [ -n "$image_sha" ]; then + echo -e "\nℹ️ Docker manifest inspect (local):" + docker manifest inspect "${image}@${image_sha}" | jq || true + fi + exit 0 + fi + + echo -e "\nℹ️ Local image not found or inspect returned empty; inspecting remote with buildx imagetools..." + set +e + raw=$(docker buildx imagetools inspect --raw "$image" 2>/dev/null || true) + set -e + + if [ -z "$raw" ]; then + echo "❌ Failed to inspect remote image with buildx imagetools: $image" + exit 1 + fi + + echo -e "\n✅ Remote manifest/index (raw):" + echo "$raw" | jq + + echo -e "\nℹ️ Attempting to pull and inspect per-platform manifests:" + echo "$raw" | jq -r '.manifests[]?.digest' | while IFS= read -r digest; do + if [ -z "$digest" ] || [ "$digest" = "null" ]; then + continue + fi + ref="${image%@*}@${digest}" + echo -e "\nℹ️ Pulling $ref (may fail for some registries)..." + set +e + docker pull "$ref" >/dev/null 2>&1 || true + pulled_rc=$? + set -e + if [ "$pulled_rc" -eq 0 ]; then + echo "ℹ️ Inspecting pulled image $ref" + docker image inspect "$ref" | jq || true + else + echo "⚠️ Could not pull $ref; skipping image inspect" + fi + done diff --git a/templates/dockerized/taskfiles/Taskfile.docker.yml b/templates/dockerized/taskfiles/Taskfile.docker.yml index 323a64d..f0f0baa 100644 --- a/templates/dockerized/taskfiles/Taskfile.docker.yml +++ b/templates/dockerized/taskfiles/Taskfile.docker.yml @@ -3,3 +3,130 @@ version: '3' silent: true tasks: + docker:login: + desc: Login to hub.docker.com and ghcr.io + cmds: + - | + set -eu + docker_username='{{.DOCKER_USERNAME}}' + github_username='{{.GITHUB_USERNAME}}' + has_dockerhub=false + has_ghcr=false + + if [ -n "$docker_username" ] && [ -n "${DOCKER_TOKEN:-}" ]; then + has_dockerhub=true + fi + + if [ -n "$github_username" ] && [ -n "${GITHUB_TOKEN:-}" ]; then + has_ghcr=true + fi + + if [ "$has_dockerhub" = false ] && [ "$has_ghcr" = false ]; then + echo "❌ No registry credentials provided. Set DOCKER_USERNAME/DOCKER_TOKEN or GITHUB_USERNAME/GITHUB_TOKEN." + exit 1 + fi + + if [ "$has_dockerhub" = true ]; then + echo "Logging into Docker Hub as $docker_username" + printf '%s' "${DOCKER_TOKEN}" | docker login -u "$docker_username" --password-stdin + else + echo "⚠️ Skipping Docker Hub login (missing DOCKER_USERNAME/DOCKER_TOKEN)" + fi + + if [ "$has_ghcr" = true ]; then + echo "Logging into GHCR as $github_username" + printf '%s' "${GITHUB_TOKEN}" | docker login ghcr.io -u "$github_username" --password-stdin + else + echo "⚠️ Skipping GHCR login (missing GITHUB_USERNAME/GITHUB_TOKEN)" + fi + + docker:cmds: + desc: Show full docker build command + cmds: + - echo -e '{{.DOCKER_BUILD_START}} {{.DOCKER_BUILD_FINISH}}' | {{.SED}} 's/--/ \\\n+ --/g' + + docker:build: + desc: Build Docker image + cmds: + - docker buildx create --use + - '{{.DOCKER_BUILD_START}} {{.DOCKER_BUILD_FINISH}}' + + docker:build:inspect: + desc: Inspect built Docker image + cmds: + - | + image_inspect_out=$(docker image inspect {{.DOCKER_NAME}}:{{.VERSION_FULL}}{{.VERSION_SUFFIX}} | jq -r) + echo -e "\nℹ️ Docker image inspect:" + echo "$image_inspect_out" | jq + + docker:push: + desc: Build and push Docker images + deps: + - task: docker:login + cmds: + - docker buildx create --use + - '{{.DOCKER_BUILD_START}} --push {{.DOCKER_BUILD_FINISH}}' + + docker:push:inspect: + desc: Inspect built Docker image + cmds: + - | + set -eu + image="{{.DOCKER_NAME}}:{{.VERSION_FULL}}{{.VERSION_SUFFIX}}" + + echo -e "\nℹ️ Trying local image inspect: $image" + set +e + image_inspect_out=$(docker image inspect "$image" 2>/dev/null || true) + rc=$? + set -e + + has_local=0 + if [ "$rc" -eq 0 ] && [ -n "$image_inspect_out" ]; then + if echo "$image_inspect_out" | jq -e 'type=="array" and (length > 0) and \ + (.[0].Id != null and .[0].Id != "")' >/dev/null 2>&1; then + has_local=1 + fi + fi + + if [ "$has_local" -eq 1 ]; then + echo -e "\n✅ Local image found. Docker image inspect:" + echo "$image_inspect_out" | jq + image_sha=$(echo "$image_inspect_out" | jq -r '.[0].Id // empty') + if [ -n "$image_sha" ]; then + echo -e "\nℹ️ Docker manifest inspect (local):" + docker manifest inspect "${image}@${image_sha}" | jq || true + fi + exit 0 + fi + + echo -e "\nℹ️ Local image not found or inspect returned empty; inspecting remote with buildx imagetools..." + set +e + raw=$(docker buildx imagetools inspect --raw "$image" 2>/dev/null || true) + set -e + + if [ -z "$raw" ]; then + echo "❌ Failed to inspect remote image with buildx imagetools: $image" + exit 1 + fi + + echo -e "\n✅ Remote manifest/index (raw):" + echo "$raw" | jq + + echo -e "\nℹ️ Attempting to pull and inspect per-platform manifests:" + echo "$raw" | jq -r '.manifests[]?.digest' | while IFS= read -r digest; do + if [ -z "$digest" ] || [ "$digest" = "null" ]; then + continue + fi + ref="${image%@*}@${digest}" + echo -e "\nℹ️ Pulling $ref (may fail for some registries)..." + set +e + docker pull "$ref" >/dev/null 2>&1 || true + pulled_rc=$? + set -e + if [ "$pulled_rc" -eq 0 ]; then + echo "ℹ️ Inspecting pulled image $ref" + docker image inspect "$ref" | jq || true + else + echo "⚠️ Could not pull $ref; skipping image inspect" + fi + done