{"id":49077308,"url":"https://github.com/devops-infra/action-container-structure-test","last_synced_at":"2026-05-22T22:05:41.202Z","repository":{"id":350875361,"uuid":"1208071451","full_name":"devops-infra/action-container-structure-test","owner":"devops-infra","description":"Container Structure Tests","archived":false,"fork":false,"pushed_at":"2026-05-20T20:31:44.000Z","size":49,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-21T02:14:06.994Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/devops-infra.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-11T19:26:07.000Z","updated_at":"2026-05-20T20:31:48.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/devops-infra/action-container-structure-test","commit_stats":null,"previous_names":["devops-infra/action-container-structure-test"],"tags_count":3,"template":false,"template_full_name":"devops-infra/template-action","purl":"pkg:github/devops-infra/action-container-structure-test","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devops-infra%2Faction-container-structure-test","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devops-infra%2Faction-container-structure-test/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devops-infra%2Faction-container-structure-test/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devops-infra%2Faction-container-structure-test/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/devops-infra","download_url":"https://codeload.github.com/devops-infra/action-container-structure-test/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devops-infra%2Faction-container-structure-test/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33372739,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-22T21:56:13.512Z","status":"ssl_error","status_checked_at":"2026-05-22T21:56:10.769Z","response_time":265,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-20T10:33:36.905Z","updated_at":"2026-05-22T22:05:41.196Z","avatar_url":"https://github.com/devops-infra.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🚀 Container Structure Test\n**GitHub Action running Google Container Structure Tests against a container image**\n\n\n## 📦 Available on\n- **Docker Hub:** [devopsinfra/action-container-structure-test:latest](https://hub.docker.com/repository/docker/devopsinfra/action-container-structure-test)\n- **GitHub Packages:** [ghcr.io/devops-infra/action-container-structure-test:latest](https://github.com/devops-infra/action-container-structure-test/pkgs/container/action-container-structure-test)\n\n\n## ✨ Features\n* Runs [GoogleContainerTools/container-structure-test](https://github.com/GoogleContainerTools/container-structure-test) in CI\n* Supports all test types: command tests, file existence tests, file content tests, metadata tests, license tests\n* Supports `docker`, `tar`, and `host` drivers\n* Exposes test totals (total / passed / failed) as Action outputs\n* Multi-platform image: `linux/amd64` and `linux/arm64`\n* Lightweight Alpine-based Docker image\n\n\n## 🔗 Related Actions\nCheck also other actions from [DevOps-Infra](https://shyper.pro/portfolio/projects/actions/)\n\n\n## 📊 Badges\n[\n![GitHub repo](https://img.shields.io/badge/GitHub-devops--infra%2Faction--container--structure--test-blueviolet.svg?style=plastic\u0026logo=github)\n![GitHub last commit](https://img.shields.io/github/last-commit/devops-infra/action-container-structure-test?color=blueviolet\u0026logo=github\u0026style=plastic\u0026label=Last%20commit)\n![Pull Request](https://github.com/devops-infra/action-container-structure-test/actions/workflows/auto-pull-request-create.yml/badge.svg)\n![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/devops-infra/action-container-structure-test?color=blueviolet\u0026label=Code%20size\u0026style=plastic\u0026logo=github)\n![GitHub license](https://img.shields.io/github/license/devops-infra/action-container-structure-test?color=blueviolet\u0026logo=github\u0026style=plastic\u0026label=License)\n](https://github.com/devops-infra/action-container-structure-test \"shields.io\")\n\u003cbr\u003e\n[\n![DockerHub](https://img.shields.io/badge/DockerHub-devopsinfra%2Faction--container--structure--test-blue.svg?style=plastic\u0026logo=docker)\n![Docker version](https://img.shields.io/docker/v/devopsinfra/action-container-structure-test?color=blue\u0026label=Version\u0026logo=docker\u0026style=plastic\u0026sort=semver)\n![Image size](https://img.shields.io/docker/image-size/devopsinfra/action-container-structure-test/latest?label=Image%20size\u0026style=plastic\u0026logo=docker)\n![Docker Pulls](https://img.shields.io/docker/pulls/devopsinfra/action-container-structure-test?color=blue\u0026label=Pulls\u0026logo=docker\u0026style=plastic)\n![Weekly Health](https://github.com/devops-infra/action-container-structure-test/actions/workflows/cron-dependency-update.yml/badge.svg)\n](https://hub.docker.com/r/devopsinfra/action-container-structure-test \"shields.io\")\n\n\n## 🏷️ Version Tags: vX, vX.Y, vX.Y.Z\nThis action supports three tag levels for flexible versioning:\n- `vX`: latest patch of the major version (e.g., `v1`).\n- `vX.Y`: latest patch of the minor version (e.g., `v1.0`).\n- `vX.Y.Z`: fixed to a specific release (e.g., `v1.0.0`).\n\n\n## 📖 API Reference\n```yaml\n    - name: Run the Action\n      uses: devops-infra/action-container-structure-test@v1.0.2\n      with:\n        image: my-image:latest\n        config: tests/structure-test.yaml\n        driver: docker\n        output: text\n        debug: false\n```\n\n### 🔧 Input Parameters\n| Input                   | Required | Default  | Description                                                                                               |\n|:------------------------|:--------:|:--------:|:----------------------------------------------------------------------------------------------------------|\n| `image`                 |    *     |          | Image to test. Required unless `image_from_oci_layout` is set. Mutually exclusive with it.                |\n| `config`                |   Yes    |          | Path(s) to test config file(s). Space or newline-separated for multiple files.                            |\n| `driver`                |    No    | `docker` | Driver to use when running tests: `docker`, `tar`, or `host`.                                             |\n| `platform`              |    No    |          | Platform to test, e.g. `linux/amd64` or `linux/arm64`. Defaults to host arch.                             |\n| `pull`                  |    No    | `false`  | Force pull the image before running tests (docker driver only).                                           |\n| `save`                  |    No    | `false`  | Preserve created containers after the test run.                                                           |\n| `quiet`                 |    No    | `false`  | Suppress test output.                                                                                     |\n| `no_color`              |    No    | `false`  | Disable colorized output.                                                                                 |\n| `output`                |    No    |  `text`  | Output format: `text`, `json`, or `junit`.                                                                |\n| `test_report`           |    No    |          | Write test results to this file path, then print it to logs. CST converts `text` to `json` automatically. |\n| `junit_suite_name`      |    No    |          | Name for the JUnit test suite (only used when `output` is `junit`).                                       |\n| `metadata`              |    No    |          | Path to image metadata file.                                                                              |\n| `runtime`               |    No    |          | Runtime to use with the docker driver (e.g. `runsc` for gVisor).                                          |\n| `force`                 |    No    | `false`  | Force run of host driver without interactive prompt.                                                      |\n| `image_from_oci_layout` |    No    |          | Path to OCI image layout directory. Mutually exclusive with `image`.                                      |\n| `default_image_tag`     |    No    |          | Default image tag when OCI layout lacks a ref annotation. Requires `image_from_oci_layout`.               |\n| `ignore_ref_annotation` |    No    | `false`  | Ignore `org.opencontainers.image.ref.name` annotation when loading OCI layout.                            |\n| `debug`                 |    No    | `false`  | Enable verbose debug logging in the action entrypoint.                                                    |\n\n\n### 📤 Output Parameters\n| Output      | Description                                          |\n|:------------|:-----------------------------------------------------|\n| `total`     | Total number of tests executed.                      |\n| `passed`    | Number of tests that passed.                         |\n| `failed`    | Number of tests that failed.                         |\n| `exit_code` | Exit code returned by `container-structure-test`.    |\n\n\n## 💻 Usage Examples\n\n### 📝 Basic Example\nRun structure tests against a Docker image using a single config file.\n\n```yaml\nname: Run structure tests on each commit\non: [push]\njobs:\n  container-structure-test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Build image\n        run: docker build -t my-image:latest .\n\n      - uses: devops-infra/action-container-structure-test@v1\n        with:\n          image: my-image:latest\n          config: tests/structure-test.yaml\n```\n\n### 🔀 Advanced Example\nRun tests with multiple config files, JSON output, and a saved report.\n\n```yaml\nname: Run structure tests on each commit\non: [push]\njobs:\n  container-structure-test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Build image\n        run: docker build -t my-image:latest .\n\n      - name: Run structure tests\n        id: cst\n        uses: devops-infra/action-container-structure-test@v1\n        with:\n          image: my-image:latest\n          config: |\n            tests/command-tests.yaml\n            tests/file-tests.yaml\n          output: json\n          test_report: /tmp/cst-report.json\n          pull: 'false'\n          debug: 'false'\n\n      - name: Show test results\n        run: |\n          echo \"Total:  ${{ steps.cst.outputs.total }}\"\n          echo \"Passed: ${{ steps.cst.outputs.passed }}\"\n          echo \"Failed: ${{ steps.cst.outputs.failed }}\"\n          echo \"Exit:   ${{ steps.cst.outputs.exit_code }}\"\n```\n\n### 🎯 Use specific version\nPick the tag level based on your stability needs:\n- `vX.Y.Z`: exact immutable release (most predictable)\n- `vX.Y`: latest patch within one minor line\n- `vX`: latest patch within one major line\n\n```yaml\nname: Run structure tests on each commit\non: [push]\njobs:\n  container-structure-test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n\n      - uses: devops-infra/action-container-structure-test@v1.0.2\n        id: pin-patch-version\n        with:\n          image: my-image:latest\n          config: tests/structure-test.yaml\n\n      - uses: devops-infra/action-container-structure-test@v1.0\n        id: pin-minor-version\n        with:\n          image: my-image:latest\n          config: tests/structure-test.yaml\n\n      - uses: devops-infra/action-container-structure-test@v1\n        id: pin-major-version\n        with:\n          image: my-image:latest\n          config: tests/structure-test.yaml\n```\n\n### 🧪 JUnit Output\nGenerate a JUnit report for test result publishing.\n\n```yaml\nname: Run structure tests on each commit\non: [push]\njobs:\n  container-structure-test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Build image\n        run: docker build -t my-image:latest .\n\n      - name: Run structure tests\n        uses: devops-infra/action-container-structure-test@v1\n        with:\n          image: my-image:latest\n          config: tests/structure-test.yaml\n          output: junit\n          junit_suite_name: container-structure-tests\n          test_report: /tmp/cst-results.xml\n```\n\n### 📦 TAR Driver\nTest an exported image without a Docker daemon (file/metadata tests only).\n\n```yaml\nname: Run structure tests on each commit\non: [push]\njobs:\n  container-structure-test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Export image as tar\n        run: docker save my-image:latest -o my-image.tar\n\n      - uses: devops-infra/action-container-structure-test@v1\n        with:\n          image: my-image.tar\n          config: tests/file-tests.yaml\n          driver: tar\n```\n\n\n## 📋 Test Config Reference\n\nContainer Structure Test configs are YAML or JSON files.\nThe current schema version is `2.0.0` and must be set in every config.\n\n```yaml\nschemaVersion: '2.0.0'\n\ncommandTests:\n  - name: \"python version\"\n    command: \"python3\"\n    args: [\"--version\"]\n    expectedOutput: [\"Python 3\\\\..*\"]\n\nfileExistenceTests:\n  - name: \"entrypoint exists\"\n    path: \"/entrypoint.sh\"\n    shouldExist: true\n    permissions: \"-rwxr-xr-x\"\n\nfileContentTests:\n  - name: \"sources list\"\n    path: \"/etc/os-release\"\n    expectedContents: [\".*alpine.*\"]\n\nmetadataTest:\n  workdir: \"/app\"\n  envVars:\n    - key: PATH\n      value: \"/usr/local/bin:.*\"\n      isRegex: true\n```\n\nFull documentation: [GoogleContainerTools/container-structure-test](https://github.com/GoogleContainerTools/container-structure-test)\n\n\n## 🏗️ CI/CD\nWorkflows included:\n- (Auto) Pull Request Create (`.github/workflows/auto-pull-request-create.yml`)\n  - Trigger: push to any branch except `master` and `dependabot/**`.\n  - Jobs:\n    - Lint\n    - Build and push multi-platform test image, and inspect manifest\n    - Create pull request\n- (Auto) Create release (`.github/workflows/auto-create-release.yml`)\n  - Trigger: `pull_request` closed and `push` to `release/**` (runs only for merged PRs from `release/`)\n  - Jobs:\n    - Lint\n    - Tagging: create `vX.Y.Z`; update `vX.Y` and `vX` (fails if full tag exists on remote)\n    - Build and push multi-platform image, and inspect manifest\n    - Publish GitHub Release\n    - Update Docker hub description\n- (Cron) Weekly dependency build (`.github/workflows/cron-dependency-update.yml`)\n  - Trigger: Weekly on Monday at 08:00 UTC\n  - Jobs:\n    - Lint\n    - Build and push multi-platform test image, and inspect manifest\n- (Manual) Update version (`.github/workflows/manual-release-create.yml`)\n  - Trigger: manual `workflow_dispatch` with `type` (`patch|minor|major|set`) xor `version` when `type=set`\npushes to `release/**` branch and creates a pull request to create a new release\n  - Jobs:\n    - Update version: bump or set; output `REL_VERSION`\n    - Build and push multi-platform image, and inspect manifest\n    - Create pull request, approve to create a release\n\n\n## 🧑‍💻 Development\nPrerequisites:\n- Docker with Buildx,\n- Task (installed via workflow or from https://taskfile.dev),\n- gnu-sed if on macOS (`brew install gnu-sed`),\n- pre-commit (optional).\n\nCommon tasks:\n```bash\n# Run all linters\ntask lint\n\n# Build multi-arch images locally (no push)\ntask docker:build\n\n# Build a local runnable image for your current architecture\ntask docker:build:local\n\n# Run container-structure-test action locally (build is required and enforced)\ntask docker:test:local IMAGE=my-image:latest CONFIG=tests/structure-test.yaml\n\n# Run with multiple config files\ntask docker:test:local IMAGE=my-image:latest CONFIG=\"tests/command-tests.yaml tests/file-tests.yaml\"\n\n# Run against OCI layout\ntask docker:test:local IMAGE_FROM_OCI_LAYOUT=./oci-layout CONFIG=tests/structure-test.yaml\n\n# Run built-in smoke test against the locally built action image\ntask docker:test:smoke\n\n# Push images (requires DOCKER_TOKEN and GITHUB_TOKEN)\nDOCKER_TOKEN=... GITHUB_TOKEN=... task docker:push\n```\n\nLocal run notes:\n- `docker:test:local` always builds the action image first via `docker:build:local`.\n- `docker:test:smoke` uses `tests/docker/local-image.yml` to verify installed binaries,\n  metadata, and cache cleanup on the built image.\n- For `DRIVER=docker` (default), Docker socket access is required.\n- Optional task variables map to action inputs, for example:\n  - `OUTPUT=json`, `PULL=true`, `PLATFORM=linux/arm64`, `DEBUG=true`\n\nPre-commit hooks:\n```bash\nbrew install pre-commit\ntask pre-commit:install\ntask pre-commit\n```\n\n\n## 🤝 Contributing\nContributions are welcome! See [CONTRIBUTING](https://github.com/devops-infra/.github/blob/master/CONTRIBUTING.md).\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n\n## 📄 License\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n\n## 💬 Support\nIf you have any questions or need help, please:\n- 📝 Create an [issue](https://github.com/devops-infra/action-container-structure-test/issues)\n- 🌟 Star this repository if you find it useful!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevops-infra%2Faction-container-structure-test","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevops-infra%2Faction-container-structure-test","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevops-infra%2Faction-container-structure-test/lists"}