{"id":34172182,"url":"https://github.com/giantswarm/retagger","last_synced_at":"2026-03-11T02:03:40.192Z","repository":{"id":20854763,"uuid":"91108575","full_name":"giantswarm/retagger","owner":"giantswarm","description":"A tool to handle the retagging of third party container images","archived":false,"fork":false,"pushed_at":"2026-02-18T01:38:25.000Z","size":33061,"stargazers_count":28,"open_issues_count":3,"forks_count":4,"subscribers_count":6,"default_branch":"main","last_synced_at":"2026-02-18T06:52:09.835Z","etag":null,"topics":["containers","devops","docker"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/giantswarm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","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":"DCO","cla":null}},"created_at":"2017-05-12T16:08:34.000Z","updated_at":"2026-02-18T01:38:28.000Z","dependencies_parsed_at":"2025-12-11T15:15:14.609Z","dependency_job_id":null,"html_url":"https://github.com/giantswarm/retagger","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/giantswarm/retagger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giantswarm%2Fretagger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giantswarm%2Fretagger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giantswarm%2Fretagger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giantswarm%2Fretagger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/giantswarm","download_url":"https://codeload.github.com/giantswarm/retagger/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giantswarm%2Fretagger/sbom","scorecard":{"id":426278,"data":{"date":"2025-08-18T07:33:28Z","repo":{"name":"github.com/giantswarm/retagger","commit":"f814716a655995443284a331cfed9fa9879dde94"},"scorecard":{"version":"v5.2.1","commit":"ab2f6e92482462fe66246d9e32f642855a691dc1"},"score":7,"checks":[{"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/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":5,"reason":"Found 16/30 approved changesets -- score normalized to 5","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/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#code-review"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Info: Found linked content: SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#security-policy"}},{"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/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#dangerous-workflow"}},{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: RenovateBot: renovate.json5:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#dependency-update-tool"}},{"name":"Maintained","score":10,"reason":"26 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"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/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":7,"reason":"dependency not pinned by hash detected -- score normalized to 7","details":["Warn: containerImage not pinned by hash: Dockerfile:5","Warn: containerImage not pinned by hash: Dockerfile:25","Warn: containerImage not pinned by hash: Dockerfile:28","Info:  12 out of  12 GitHub-owned GitHubAction dependencies pinned","Info:   6 out of   6 third-party GitHubAction dependencies pinned","Info:   0 out of   3 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/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/zz_generated.add-team-labels.yaml:1","Warn: no topLevel permission defined: .github/workflows/zz_generated.add-to-project-board.yaml:1","Warn: no topLevel permission defined: .github/workflows/zz_generated.create_release.yaml:1","Warn: no topLevel permission defined: .github/workflows/zz_generated.create_release_pr.yaml:1","Warn: no topLevel permission defined: .github/workflows/zz_generated.fix_vulnerabilities.yaml:1","Warn: no topLevel permission defined: .github/workflows/zz_generated.gitleaks.yaml:1","Warn: no topLevel permission defined: .github/workflows/zz_generated.run_ossf_scorecard.yaml:1","Info: topLevel 'contents' permission set to 'read': .github/workflows/zz_generated.validate_changelog.yaml:16","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/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#token-permissions"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#signed-releases"}},{"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/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#cii-best-practices"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#license"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#vulnerabilities"}},{"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/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#branch-protection"}},{"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/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#fuzzing"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 18 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#sast"}},{"name":"CI-Tests","score":10,"reason":"18 out of 18 merged PRs checked by a CI test -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#ci-tests"}},{"name":"Contributors","score":10,"reason":"project has 25 contributing companies or organizations","details":["Info: found contributions from: KoelnAPI, acmfi, alloy-rs, clickhouse, cncf, codeformuenster, elastic, enviroCar, giant swarm, giant swarm gmbh, giantswarm, gravitational, ithacaxyz, k8spin, kubernetes, kubernetes-sigs, netzbegruenung, paradigmxyz, paradigmxyz @ithacaxyz, prometheus-community, protocolguild, sensebox, ssvlabs, tektoncd, tgndevs"],"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#contributors"}}]},"last_synced_at":"2025-08-19T02:18:55.357Z","repository_id":20854763,"created_at":"2025-08-19T02:18:55.357Z","updated_at":"2025-08-19T02:18:55.357Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30367810,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T21:41:54.280Z","status":"online","status_checked_at":"2026-03-11T02:00:07.027Z","response_time":84,"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":["containers","devops","docker"],"created_at":"2025-12-15T11:41:26.619Z","updated_at":"2026-03-11T02:03:40.171Z","avatar_url":"https://github.com/giantswarm.png","language":"Go","readme":"[![CircleCI](https://dl.circleci.com/status-badge/img/gh/giantswarm/retagger/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/giantswarm/retagger/tree/main)\n\n# retagger\n\n\u003e A tool to handle the retagging of third-party docker images and make them\n  available in their own registries.\n\n## What does retagger do, exactly?\n\n`retagger` is first and foremost a CircleCI workflow that runs every day at 21:30\nUTC and on every merge to the main branch. It utilizes [skopeo][skopeo] and\n[custom golang code](main.go) to take upstream docker images, rename them if\nnecessary, and push them to Giant Swarm's container registries: `gsoci.azurecr.io` and\n`giantswarm-registry.cn-shanghai.cr.aliyuncs.com`. It is capable of working\nwith `v1`, `v2`, and `OCI` registries, as well as retagging multi-architecture\nimages.\n\n\u003e 💡Please note it **is not responsible** for pushing images to neither\n`docker.io/giantswarm`, nor `azurecr.io/giantswarm` container registries.\n\n## How to add your image to the job\n\nYou've come to the right place. Pick one of the following methods. For both methods, ensure that the repository exists in the desired container registry first.\n\n### Plain copy\n\nYou do **not** need any customizations. Great!\n1. Find a `skopeo-*.yaml` file in [images](images/) matching your upstream\n   container registry's name. Create a new one, if necessary.\n2. Add a tag, SHA, or a semantic version constraint for your image. Refer to\n   [Skopeo](#skopeo) section or existing files for format definition.\n3. If you haven't created a new file, that's it. You're set. Otherwise, continue\n   following the steps.\n4. Open [CircleCI config][ciconf] and add your file to both `retag-registry`\n   steps under `matrix.parameters.images_file`.\n\n### Manual copy\n\nYou need to copy a few tags, it's a one-off situation. You can use `docker\npull/docker tag/docker push` combination or the below `skopeo` snippet:\n\n```bash\n$ skopeo sync --src docker --dest docker --all --keep-going crossplane/crossplane:v1.11.0 docker.io/giantswarm/\n```\n\n## Image list formats\n\n### Skopeo\n\nThe basic file format looks as follows:\n`images/skopeo-registry-example-com.yaml`\n```yaml\nregistry.example.com:\n    images:\n        redis:\n            - \"1.0\"\n            - \"2.0\"\n            - \"sha256:0000000000000000000000000000000011111111111111111111111111111111\"\n    images-by-semver:\n        alpine: \"\u003e= 3.17\"\n```\n\nThe full specification is available in [upstream skopeo-sync docs][skopeo-sync\ndocs]. Semantic version constraint documentation is available in\n[Masterminds/semver docs][masterminds docs].\n\n### Custom image builds\n\nCustom container image builds were moved to: https://github.com/giantswarm/custom-container-images.\n\n### Renamed images\n\nRenamed images are represented as an array of `RenamedImages` objects. Please see the definition below:\n\n```golang\ntype RenamedImage struct {\n\t// Image is the full name of the image to pull.\n\t// Example: \"alpine\", \"docker.io/giantswarm/app-operator\", or\n\t// \"ghcr.io/fluxcd/kustomize-controller\"\n\tImage string `yaml:\"image\"`\n\t// TagOrPattern is used to filter image tags. All tags matching the pattern\n\t// will be retagged. Required if SHA is specified.\n\t// Example: \"v1.[234].*\" or \".*-stable\"\n\tTagOrPattern string `yaml:\"tag_or_pattern,omitempty\"`\n\t// SHA is used to filter image tags. If SHA is specified, it will take\n\t// precedence over TagOrPattern. However TagOrPattern is still required!\n\t// Example: 234cb88d3020898631af0ccbbcca9a66ae7306ecd30c9720690858c1b007d2a0\n\tSHA string `yaml:\"sha,omitempty\"`\n\t// Semver is used to filter image tags by semantic version constraints. All\n\t// tags satisfying the constraint will be retagged.\n\tSemver string `yaml:\"semver,omitempty\"`\n\t// Filter is a regexp pattern used to extract a part of the tag for Semver\n\t// comparison. First matched group will be supplied for semver comparison.\n\t// Example:\n\t//   Filter: \"(.+)-alpine\"  -\u003e  Image tag: \"3.12-alpine\" -\u003e Comparison: \"3.12\u003e=3.10\"\n\t//   Semver: \"\u003e= 3.10\"          Extracted group: \"3.12\"\n\tFilter string `yaml:\"filter,omitempty\"`\n\t// AddTagSuffix is an extra string to append to the tag.\n\t// Example: \"giantswarm\", the tag would become \"\u003ctag\u003e-giantswarm\"\n\tAddTagSuffix string `yaml:\"add_tag_suffix,omitempty\"`\n\t// OverrideRepoName allows user to rewrite the name of the image entirely.\n\t// Example: \"alpinegit\", so \"alpine\" would become\n\t// \"gsoci.azurecr.io/giantswarm/alpinegit\"\n\tOverrideRepoName string `yaml:\"override_repo_name,omitempty\"`\n\t// StripSemverPrefix removes the initial 'v' in 'v1.2.3' if enabled. Works\n\t// only when Semver is defined.\n\tStripSemverPrefix bool `yaml:\"strip_semver_prefix,omitempty\"`\n}\n```\n\n## Contributing\n\nPlease refer to [CONTRIBUTING.md](CONTRIBUTING.md).\n\n[skopeo]: https://github.com/containers/skopeo\n[skopeo-sync docs]: https://github.com/kubasobon/skopeo/blob/semver/docs/skopeo-sync.1.md#yaml-file-content-used-source-for---src-yaml\n[masterminds docs]: https://github.com/Masterminds/semver/tree/v3.2.0#basic-comparisons\n\n[ciconf]: .circleci/config.yml\n[renamed]: images/renamed-images.yaml\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiantswarm%2Fretagger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgiantswarm%2Fretagger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiantswarm%2Fretagger/lists"}