diff --git a/Taskfile.docker.yml b/Taskfile.docker.yml index 1407f3b..e2e1260 100644 --- a/Taskfile.docker.yml +++ b/Taskfile.docker.yml @@ -51,6 +51,90 @@ tasks: - docker buildx create --use - '{{.DOCKER_BUILD_START}} {{.DOCKER_BUILD_FINISH}}' + docker:build:local: + desc: Build local runnable Docker image for current architecture + cmds: + - | + set -eu + arch="$(uname -m)" + case "${arch}" in + x86_64|amd64) target_arch="amd64" ;; + aarch64|arm64) target_arch="arm64" ;; + *) + echo "❌ Unsupported local architecture: ${arch}" + exit 1 + ;; + esac + + docker build \ + --build-arg TARGETARCH="${target_arch}" \ + --tag "{{.DOCKER_NAME}}:{{.VERSION_FULL}}{{.VERSION_SUFFIX}}" \ + --file Dockerfile \ + . + + docker:test:local: + desc: Run container-structure-test action locally (requires local build) + deps: + - task: docker:build:local + requires: + vars: [CONFIG] + cmds: + - | + set -eu + image='{{default "" .IMAGE}}' + image_from_oci_layout='{{default "" .IMAGE_FROM_OCI_LAYOUT}}' + config='{{.CONFIG}}' + + if [ -z "${image}" ] && [ -z "${image_from_oci_layout}" ]; then + echo "❌ Provide IMAGE= or IMAGE_FROM_OCI_LAYOUT=" + exit 1 + fi + if [ -n "${image}" ] && [ -n "${image_from_oci_layout}" ]; then + echo "❌ IMAGE and IMAGE_FROM_OCI_LAYOUT are mutually exclusive" + exit 1 + fi + if [ ! -S /var/run/docker.sock ] && [ '{{default "docker" .DRIVER}}' = 'docker' ]; then + echo "❌ Docker socket not available at /var/run/docker.sock (required for DRIVER=docker)" + exit 1 + fi + + docker run --rm \ + -v "$PWD:/github/workspace" \ + -w /github/workspace \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -e INPUT_IMAGE="${image}" \ + -e INPUT_IMAGE_FROM_OCI_LAYOUT="${image_from_oci_layout}" \ + -e INPUT_CONFIG="${config}" \ + -e INPUT_DRIVER='{{default "docker" .DRIVER}}' \ + -e INPUT_PLATFORM='{{default "" .PLATFORM}}' \ + -e INPUT_PULL='{{default "false" .PULL}}' \ + -e INPUT_SAVE='{{default "false" .SAVE}}' \ + -e INPUT_QUIET='{{default "false" .QUIET}}' \ + -e INPUT_NO_COLOR='{{default "false" .NO_COLOR}}' \ + -e INPUT_OUTPUT='{{default "text" .OUTPUT}}' \ + -e INPUT_TEST_REPORT='{{default "" .TEST_REPORT}}' \ + -e INPUT_JUNIT_SUITE_NAME='{{default "" .JUNIT_SUITE_NAME}}' \ + -e INPUT_METADATA='{{default "" .METADATA}}' \ + -e INPUT_RUNTIME='{{default "" .RUNTIME}}' \ + -e INPUT_FORCE='{{default "false" .FORCE}}' \ + -e INPUT_DEFAULT_IMAGE_TAG='{{default "" .DEFAULT_IMAGE_TAG}}' \ + -e INPUT_IGNORE_REF_ANNOTATION='{{default "false" .IGNORE_REF_ANNOTATION}}' \ + -e INPUT_DEBUG='{{default "false" .DEBUG}}' \ + devopsinfra/action-container-structure-test:v1 + + docker:test:smoke: + desc: Smoke test local action image with container-structure-test + deps: + - task: docker:build:local + cmds: + - | + set -eu + task docker:test:local \ + IMAGE="{{.DOCKER_NAME}}:{{.VERSION_FULL}}{{.VERSION_SUFFIX}}" \ + CONFIG="tests/docker/local-image.yml" \ + DRIVER=docker \ + OUTPUT=text + docker:build:inspect: desc: Inspect built Docker image cmds: diff --git a/Taskfile.variables.yml b/Taskfile.variables.yml index d2574f5..f1ca7f1 100644 --- a/Taskfile.variables.yml +++ b/Taskfile.variables.yml @@ -7,7 +7,6 @@ env: TERM: xterm-256color vars: - # System context SED: sh: | if [ "$(uname -s)" = "Darwin" ]; then @@ -30,8 +29,6 @@ vars: fi PROJECT_DIR_NAME: sh: basename "$PWD" - - # Container metadata DOCKER_IMAGE: '{{.DOCKER_IMAGE | default .PROJECT_DIR_NAME}}' GITHUB_REPO: '{{.GITHUB_REPO | default .PROJECT_DIR_NAME}}' DOCKER_ORG_NAME: '{{.DOCKER_ORG_NAME | default "devopsinfra"}}' @@ -63,8 +60,6 @@ vars: LABEL_HOMEPAGE: '{{.LABEL_HOMEPAGE | default "https://shyper.pro"}}' LABEL_VENDOR: '{{.LABEL_VENDOR | default "DevOps-Infra"}}' LABEL_LICENSE: '{{.LABEL_LICENSE | default "MIT"}}' - - # Build context CONTEXT: '{{.CONTEXT | default "."}}' DOCKERFILE: '{{.DOCKERFILE | default "Dockerfile"}}' PLATFORMS: '{{.PLATFORMS | default "linux/amd64,linux/arm64"}}' @@ -120,8 +115,6 @@ vars: sh: echo "{{.VERSION_FROM_ACTION_YML}}" | awk -F\. '{print $1}' MINOR_FROM_ACTION_YML: sh: echo "{{.VERSION_FROM_ACTION_YML}}" | awk -F\. '{print $1"."$2}' - - # Git metadata GIT_SHA: sh: git rev-parse HEAD 2>/dev/null || echo 0000000000000000000000000000000000000000 GIT_SHORT_SHA: @@ -133,7 +126,6 @@ vars: else git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown" fi - # Labels for http://label-schema.org/rc1/#build-time-labels # And for https://github.com/opencontainers/image-spec/blob/master/annotations.md ANNOTATIONS: >- diff --git a/Taskfile.yml b/Taskfile.yml index 45abad0..89d55c8 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -14,7 +14,6 @@ includes: taskfile: ./Taskfile.docker.yml flatten: true - tasks: default: desc: List tasks diff --git a/tests/docker/local-image.yml b/tests/docker/local-image.yml new file mode 100644 index 0000000..8a223d6 --- /dev/null +++ b/tests/docker/local-image.yml @@ -0,0 +1,34 @@ +schemaVersion: 2.0.0 + +commandTests: + - name: OS version check + command: cat + args: [/etc/os-release] + expectedOutput: [VERSION_ID="25\.10"] + + - name: Required tools installed + command: bash + args: + - -lc + - command -v bash >/dev/null 2>&1 && command -v git >/dev/null 2>&1 && command -v git-lfs >/dev/null 2>&1 + + - name: Apt cache cleaned + command: bash + args: + - -lc + - test ! -d /var/lib/apt/lists || test -z "$(find /var/lib/apt/lists -mindepth 1 -maxdepth 1 2>/dev/null)" + + - name: Temporary apt artifacts removed + command: bash + args: + - -lc + - test ! -e /git-lfs*.deb +fileExistenceTests: + - name: entrypoint exists + path: /entrypoint.sh + shouldExist: true + permissions: -rwxr-xr-x + +metadataTest: + workdir: /github/workspace + entrypoint: [/entrypoint.sh]