{"id":23826127,"url":"https://github.com/appuio/seiso","last_synced_at":"2025-09-07T08:31:39.285Z","repository":{"id":40310158,"uuid":"222490687","full_name":"appuio/seiso","owner":"appuio","description":"Seiso (清掃). Clean up your Docker image registry and Kubernetes resources.","archived":false,"fork":false,"pushed_at":"2025-09-01T16:39:21.000Z","size":500,"stargazers_count":4,"open_issues_count":21,"forks_count":3,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-09-01T18:27:32.168Z","etag":null,"topics":["docker","image-cleanup","kubernetes","openshift","vshn-project-ignore"],"latest_commit_sha":null,"homepage":"https://github.com/appuio/seiso/releases","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/appuio.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":null,"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":"2019-11-18T16:13:30.000Z","updated_at":"2024-12-02T13:34:53.000Z","dependencies_parsed_at":"2023-09-26T21:12:16.500Z","dependency_job_id":"336b10e1-8ba8-43e6-b283-6507e5937bf6","html_url":"https://github.com/appuio/seiso","commit_stats":null,"previous_names":["appuio/image-cleanup"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/appuio/seiso","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appuio%2Fseiso","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appuio%2Fseiso/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appuio%2Fseiso/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appuio%2Fseiso/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/appuio","download_url":"https://codeload.github.com/appuio/seiso/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appuio%2Fseiso/sbom","scorecard":{"id":204191,"data":{"date":"2025-08-11","repo":{"name":"github.com/appuio/seiso","commit":"752b25e291e8e8790064af722a79eec8cc0c7c99"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.3,"checks":[{"name":"Code-Review","score":7,"reason":"Found 3/4 approved changesets -- score normalized to 7","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/lint.yml:1","Warn: no topLevel permission defined: .github/workflows/master.yml:1","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/appuio/seiso/lint.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/appuio/seiso/lint.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/master.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/appuio/seiso/master.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/master.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/appuio/seiso/master.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/appuio/seiso/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/appuio/seiso/release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/appuio/seiso/release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/appuio/seiso/release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/appuio/seiso/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/appuio/seiso/test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/appuio/seiso/test.yml/master?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1","Info:   0 out of   8 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   3 third-party GitHubAction dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: BSD 3-Clause \"New\" or \"Revised\" License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/master.yml:9"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Signed-Releases","score":8,"reason":"5 out of the last 5 releases have a total of 5 signed artifacts.","details":["Info: signed release artifact: checksums.txt.sig: https://github.com/appuio/seiso/releases/tag/v1.0.0","Info: signed release artifact: checksums.txt.sig: https://github.com/appuio/seiso/releases/tag/v0.8.0","Info: signed release artifact: checksums.txt.sig: https://github.com/appuio/seiso/releases/tag/v0.7.2","Info: signed release artifact: checksums.txt.sig: https://github.com/appuio/seiso/releases/tag/v0.7.1","Info: signed release artifact: checksums.txt.sig: https://github.com/appuio/seiso/releases/tag/v0.7.0","Warn: release artifact v1.0.0 does not have provenance: https://api.github.com/repos/appuio/seiso/releases/52613716","Warn: release artifact v0.8.0 does not have provenance: https://api.github.com/repos/appuio/seiso/releases/42605149","Warn: release artifact v0.7.2 does not have provenance: https://api.github.com/repos/appuio/seiso/releases/41056649","Warn: release artifact v0.7.1 does not have provenance: https://api.github.com/repos/appuio/seiso/releases/34047142","Warn: release artifact v0.7.0 does not have provenance: https://api.github.com/repos/appuio/seiso/releases/31689227"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"14 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2024-2456 / GHSA-449p-3h89-pw88","Warn: Project is vulnerable to: GO-2024-2466 / GHSA-mw99-9chc-xw7r","Warn: Project is vulnerable to: GO-2025-3367 / GHSA-r9px-m959-cxf4","Warn: Project is vulnerable to: GO-2025-3368 / GHSA-v725-9546-7q7m","Warn: Project is vulnerable to: GO-2022-0962 / GHSA-7hfp-qfw3-5jxh","Warn: Project is vulnerable to: GO-2022-1165 / GHSA-53c4-hhmh-vw5q","Warn: Project is vulnerable to: GO-2022-1166 / GHSA-67fx-wx78-jx33","Warn: Project is vulnerable to: GO-2022-1167 / GHSA-6rx9-889q-vv2r","Warn: Project is vulnerable to: GO-2023-1547 / GHSA-pwcw-6f5g-gxf8","Warn: Project is vulnerable to: GO-2024-2554 / GHSA-v53g-5gjp-272r","Warn: Project is vulnerable to: GO-2024-2575 / GHSA-r53h-jv2g-vpx6","Warn: Project is vulnerable to: GO-2025-3601 / GHSA-4hfp-h4cw-hj8p","Warn: Project is vulnerable to: GO-2025-3602 / GHSA-5xqw-8hwv-wg92","Warn: Project is vulnerable to: GO-2025-3802 / GHSA-557j-xg8c-q2mm"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-16T23:21:02.171Z","repository_id":40310158,"created_at":"2025-08-16T23:21:02.171Z","updated_at":"2025-08-16T23:21:02.171Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273175318,"owners_count":25058526,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-01T02:00:09.058Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["docker","image-cleanup","kubernetes","openshift","vshn-project-ignore"],"created_at":"2025-01-02T12:16:05.150Z","updated_at":"2025-09-07T08:31:38.921Z","avatar_url":"https://github.com/appuio.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Seiso\n\n[![](https://img.shields.io/github/workflow/status/appuio/seiso/Build)](https://github.com/appuio/seiso/actions)\n[![](https://img.shields.io/github/v/release/appuio/seiso)](https://github.com/appuio/seiso/releases)\n![](https://img.shields.io/github/go-mod/go-version/appuio/seiso)\n[![](https://img.shields.io/github/downloads/appuio/seiso/total)](https://github.com/appuio/seiso/releases)\n[![](https://img.shields.io/docker/pulls/appuio/seiso)](https://img.shields.io/docker/pulls/appuio/seiso)\n[![](https://img.shields.io/github/license/appuio/seiso)](https://github.com/appuio/seiso/blob/master/LICENSE)\n\nInspired by Robert C. Martin's book, [Clean Code](https://www.investigatii.md/uploads/resurse/Clean_Code.pdf), foreword, page xx:\n\n\u003e Seisō (清掃), Japanese for “cleaning” (think “shine” in English):\n\u003e Keep the workplace free of hanging wires, grease, scraps, and waste.\n\n## Clean up your container registry and Kubernetes resources\n\n*Seiso* is a CLI client that helps you clean up container resources.\n\n* Unused images in your container registry (identified by Image Stream Tags\n  in an [Image Stream](https://blog.openshift.com/image-streams-faq/) in OpenShift)\n\n* Superfluous [ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#understanding-configmaps-and-pods)s\n  in your Kubernetes cluster (e.g. generated by the Kustomize [configMapGenerator](\n  https://kubectl.docs.kubernetes.io/pages/reference/kustomize.html#configmapgenerator))\n\n* Superfluous [Secret](https://kubernetes.io/docs/concepts/configuration/secret/)\n  objects in your Kubernetes cluster (e.g. generated by the Kustomize [secretGenerator](\n  https://kubectl.docs.kubernetes.io/pages/reference/kustomize.html#secretgenerator))\n\n* Empty [Namespaces](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/)\n  in your Kubernetes cluster.\n\n## Kubernetes version support\nSeiso \u003e= 1.0 only supports Kubernetes \u003e= 1.18\n\n## Usage\n\n```console\nseiso --help\n```\n```console\nseiso image --help\nseiso image history --help\nseiso image orphans --help\nseiso configmaps --help\nseiso secrets --help\nseiso namespaces --help\n```\n\n\n## Why should I use this tool?\n\n*Seiso* is intended to be used in application lifecycle management on application\ncontainer platforms and with automatic deployment processes (CI/CD pipelines).\n\nKubernetes distributions and tools allow you to easily create or add new\nresources that allow sophisticated, well-designed deployment processes.\nFor example, you may want to tag every application container image you build\nwith the [Git commit SHA-1 hash](https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection)\ncorresponding to the revision in source control that it was built from.\nYou may use [Kustomize](https://kustomize.io/) to generate `ConfigMap` and\n`Secret` objects for your Kubernetes deployment using the [configMapGenerator or\nsecretGenerator](https://kubectl.docs.kubernetes.io/pages/reference/kustomize.html)\nfeature, which creates a history of rolled out configurations that provides you\nwith both a configuration audit trail and a safe way to roll back application\nstates.\n\nWhile this is all convenient, those features were designed to create resources\nbut not to clean them up again. As a result, those resources will pile up, incur\nadditional cost for storage, cause confusion, or on (shared) application container\nenvironments you may hit a quota limit after a while.\n\n```\nThe ImageStream \"application\" is invalid: []: Internal error: ImageStream.image.openshift.io \"application\" is forbidden:\n requested usage of openshift.io/image-tags exceeds the maximum limit per openshift.io/ImageStream (51 \u003e 50)\n```\n\n## How does it work?\n\n*Seiso* uses different strategies to identify resources to be cleaned up.\n\n1. It analyzes a Git repository and compares its history with the target\n   image registry, removing old and unused image tags according to customizable rules.\n\n1. It can be used more aggressively by deleting dangling image tags, \"orphans\",\n   that happen to exist when the Git history is altered (e.g. by force-pushing).\n\n1. It can identify `ConfigMap` resources by labels that are sufficiently old to be deleted.\n\n1. It can identify `Secret` resources by labels that are sufficiently old to be deleted.\n\n*Seiso* is opinionated, e.g. with respect to naming conventions of image tags,\neither by relying on a long Git SHA-1 value (`namespace/app:a3d0df2c5060b87650df6a94a0a9600510303003`)\nor a Git tag following semantic versioning (`namespace/app:v1.2.3`).\n\nThe cleanup **runs in dry-mode by default**. Only when the `--delete` flag\nis specified, it will actually delete the identified resources. This should\nprevent accidental deletions during verifications or test runs.\n\n## Caveats and known issues\n\n* Currently, only OpenShift image registries are supported.\n\n* **Please watch out for shallow clones**, as the Git history might be missing,\n  it would in some cases also undesirably delete image tags.\n\n## Usage Imagestream\n\nThe following examples assume the namespace `namespace`, and image stream\nnamed `app`. For the image cleanup to work, you need to be logged in to the target\ncluster, as the tool will indirectly read your kubeconfig file.\n\nFor the following examples, we will assume the following Git history,\nwith `c6` being the latest commit in branch `c`:\n\n```\na1\na2\n- b3\n- b4\na5\n- c6\n```\n\nIn all cases, it is assumed that the Git repository is already checked out in the desired branch.\n\n### Example: Keep the latest 2 image tags\n\nLet's assume target branch is `a`:\n\n```console\nseiso images history -n namespace app --keep 2\n```\nor, alternatively\n```console\nseiso images history namespace/app --keep 2\n```\nOnly the image tag `a1` would be deleted (only current branch is compared).\n\n### Example: Keep no image tags\n\n```console\nseiso images history namespace/app --keep 0\n```\nThis would delete `a1` and `a2`, but *not* `a5`, as this image is being actively used by a Pod.\n\n### Example: Delete orphaned images\n\n```console\nseiso images orphans -n namespace app --older-than 7d\n```\nor, alternatively\n```console\nseiso images orphans namespace/app --older-than 7d\n```\nThis would delete `a1`, `a2`, `b3` and `b4`, if we assume that `a5` is being actively used,\nand `c6` is younger than 7d (image tag push date, not commit date).\n\nThat means it will also look in other branches too. It also deletes amended/force-pushed commits,\nwhich do not show up in the history anymore, but would still be available in the registry.\n\nThis is very useful in cases where the images from feature branches are being pushed to a `dev` namespace,\nbut need to be cleaned up after some time. In the `production` namespace, we can apply different cleanup rules.\n\n### Example: Delete versioned image tags\n\nLet's assume we have image tagged according to semver:\n```\nv1.9.3\nv1.10.0\nv1.10.1\n```\n\n```console\nseiso images history namespace/app --keep 2 --tags\n```\nThis would delete `v1.9.3` as expected, since the `--sort` flag is `version` by default (including support for v prefix).\nIf `alphabetic`, the order for semver tags is reversed (probably undesired). For date-based tags, `alphabetic` sorting\nflag might be better suitable, e.g. `2020-03-17`.\n\n## Usage ConfigMaps and Secrets\n\nThe following examples assume the namespace `namespace`. For the seiso to work, you need to be logged in to the target cluster, as the tool will indirectly read your kubeconfig file.\n\nFor below examples, we will assume the following ConfigMaps and Secrets defined\nin the cluster.\n\n```\nConfigMaps:\n - Name: C1\n   Labels: app=example,env=production\n   Used: yes\n   Age: 1m\n - Name: C2\n   Labels: app=example,env=staging\n   Used: no\n   Age: 2m\n - Name: C3\n   Labels: app=example\n   Used: no\n   Age: 1d\n - Name: C4\n   Labels: app=example\n   Used: no\n   Age: 1w\n\nSecrets\n - Name: S1\n   Labels: app=example,env=prod,config=default\n   Used: no\n   Age: 1w\n - Name: S2\n   Labels: app=example,env=staging,config=default\n   Used: no\n   Age: 1w\n```\n\n### Example: Delete unused ConfigMaps\n\n```console\nseiso configmaps -n mynamespace -l app=example --keep 1 --older-than=1d\n```\nThis would delete unused ConfigMaps older than 5 hours, from the second element (sorted in descending order)\nand that have label `app=example`, more precisely `C4`.\n\n### Example: Delete unused Secrets\n\n```console\nseiso secrets -n mynamespace -l app=example -l config=default --keep 0 --older-than=2w\n```\nThis would delete secrets older than 2 weeks with labels `app=example` and `config=default`, more precisely `S1 and S2`.\n\n## Migrate from legacy cleanup plugin\n\nProjects using the legacy `oc` cleanup plugin can be migrated to `seiso` as follows\n\n```console\noc -n \"$OPENSHIFT_PROJECT\" plugin cleanup \"$APP_NAME\" -p \"$PWD\" -f=y\n```\nbecomes:\n```console\nseiso -n \"$OPENSHIFT_PROJECT\" image history \"$APP_NAME\" --delete\n```\nWe suggest cleaning up orphan image tags in addition, e.g.\n```console\nseiso -n \"$OPENSHIFT_PROJECT\" image orphans \"$APP_NAME\" --delete --older-than 1w\n```\n\n## Development\n\nRequirements:\n\n* go\n* goreleaser\n* Docker\n\nRun code during development:\n```console\ngo run main.go\n```\n\nReformat all Go code:\n```console\nmake fmt\n```\n\nRun test suite:\n```console\nmake test\n```\n\nBuild seiso binary:\n```console\nmake clean build\n```\n\nBuild binaries for all target distributions:\n```console\nmake clean dist\n```\n\nRun seiso using its container image:\n```\ndocker run --rm -it appuio/seiso:\u003ctag\u003e\n```\n\n### Release\n\nPush a git tag with the scheme `vX.Y.Z` (semver).\n\n## Environment variables\n\nAll CLI flags can be specified also with Environment variables. Just replace dashes with underscore and capitalize the name,\ne.g.\n```console\nexport KEEP=4\nseiso images history namespace/app\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappuio%2Fseiso","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fappuio%2Fseiso","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappuio%2Fseiso/lists"}