{"id":13645680,"url":"https://github.com/lunarway/release-manager","last_synced_at":"2025-08-26T07:12:32.862Z","repository":{"id":34584667,"uuid":"172056887","full_name":"lunarway/release-manager","owner":"lunarway","description":"GitOps release manager for Kubernetes configuration repositories","archived":false,"fork":false,"pushed_at":"2025-08-20T02:15:59.000Z","size":2653,"stargazers_count":85,"open_issues_count":7,"forks_count":7,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-08-20T04:38:05.055Z","etag":null,"topics":["gitops","golang","kubernetes","squad-aura"],"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/lunarway.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":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-02-22T11:44:40.000Z","updated_at":"2025-08-13T22:08:03.000Z","dependencies_parsed_at":"2023-10-13T01:44:28.380Z","dependency_job_id":"63eb29b9-0f87-4fe7-bc3b-60f09698238b","html_url":"https://github.com/lunarway/release-manager","commit_stats":null,"previous_names":[],"tags_count":168,"template":false,"template_full_name":null,"purl":"pkg:github/lunarway/release-manager","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lunarway%2Frelease-manager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lunarway%2Frelease-manager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lunarway%2Frelease-manager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lunarway%2Frelease-manager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lunarway","download_url":"https://codeload.github.com/lunarway/release-manager/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lunarway%2Frelease-manager/sbom","scorecard":{"id":526887,"data":{"date":"2025-08-11","repo":{"name":"github.com/lunarway/release-manager","commit":"ebfb70f4475155db40fe3b7699a9ca91171f8c3b"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.7,"checks":[{"name":"Code-Review","score":10,"reason":"all changesets reviewed","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":"Maintained","score":4,"reason":"5 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/build.yml:1","Warn: no topLevel permission defined: .github/workflows/codeql-analysis.yml:1","Warn: no topLevel permission defined: .github/workflows/release-check.yml:1","Warn: no topLevel permission defined: .github/workflows/release-drafter.yml:1","Warn: topLevel 'contents' permission set to 'write': .github/workflows/release.yml:8","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":"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":"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":"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: Apache License 2.0: 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":"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/build.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/lunarway/release-manager/build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/lunarway/release-manager/build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/lunarway/release-manager/build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/lunarway/release-manager/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/lunarway/release-manager/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/lunarway/release-manager/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/lunarway/release-manager/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-check.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/lunarway/release-manager/release-check.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-check.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/lunarway/release-manager/release-check.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-check.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/lunarway/release-manager/release-check.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-drafter.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/lunarway/release-manager/release-drafter.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/lunarway/release-manager/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/lunarway/release-manager/release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/lunarway/release-manager/release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/lunarway/release-manager/release.yml/master?enable=pin","Warn: containerImage not pinned by hash: Dockerfile-daemon:1","Warn: containerImage not pinned by hash: Dockerfile-daemon-goreleaser:1","Warn: containerImage not pinned by hash: Dockerfile-server:1","Warn: containerImage not pinned by hash: Dockerfile-server:16: pin your Docker image by updating alpine:3.21.2 to alpine:3.21.2@sha256:56fa17d2a7e7f168a043a2712e63aed1f8543aeafdcee47c58dcffe38ed51099","Warn: containerImage not pinned by hash: Dockerfile-server-goreleaser:1: pin your Docker image by updating alpine:3.21.2 to alpine:3.21.2@sha256:56fa17d2a7e7f168a043a2712e63aed1f8543aeafdcee47c58dcffe38ed51099","Info:   0 out of  11 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   4 third-party GitHubAction dependencies pinned","Info:   0 out of   5 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":"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":"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":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.32.1 not signed: https://api.github.com/repos/lunarway/release-manager/releases/215084203","Warn: release artifact v0.32.0 not signed: https://api.github.com/repos/lunarway/release-manager/releases/209765258","Warn: release artifact v0.31.1 not signed: https://api.github.com/repos/lunarway/release-manager/releases/189652035","Warn: release artifact v0.31.0 not signed: https://api.github.com/repos/lunarway/release-manager/releases/174055812","Warn: release artifact v0.30.1 not signed: https://api.github.com/repos/lunarway/release-manager/releases/170509028","Warn: release artifact v0.32.1 does not have provenance: https://api.github.com/repos/lunarway/release-manager/releases/215084203","Warn: release artifact v0.32.0 does not have provenance: https://api.github.com/repos/lunarway/release-manager/releases/209765258","Warn: release artifact v0.31.1 does not have provenance: https://api.github.com/repos/lunarway/release-manager/releases/189652035","Warn: release artifact v0.31.0 does not have provenance: https://api.github.com/repos/lunarway/release-manager/releases/174055812","Warn: release artifact v0.30.1 does not have provenance: https://api.github.com/repos/lunarway/release-manager/releases/170509028"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release-check.yml:10"],"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":"Vulnerabilities","score":0,"reason":"13 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2022-0635","Warn: Project is vulnerable to: GO-2022-0646","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-2024-3321 / GHSA-v778-237x-gjrc","Warn: Project is vulnerable to: GO-2025-3487 / GHSA-hcg3-q754-cr77","Warn: Project is vulnerable to: GO-2024-2687 / GHSA-4v7x-pqxf-cx7m","Warn: Project is vulnerable to: GO-2024-3333","Warn: Project is vulnerable to: GO-2025-3503 / GHSA-qxp5-gwg8-xv66","Warn: Project is vulnerable to: GO-2025-3595 / GHSA-vvgc-356p-c3xw","Warn: Project is vulnerable to: GO-2024-2611 / GHSA-8r3f-844c-mc37"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":9,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 26 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"}}]},"last_synced_at":"2025-08-20T04:38:11.020Z","repository_id":34584667,"created_at":"2025-08-20T04:38:11.020Z","updated_at":"2025-08-20T04:38:11.020Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272187667,"owners_count":24888642,"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-08-26T02:00:07.904Z","response_time":60,"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":["gitops","golang","kubernetes","squad-aura"],"created_at":"2024-08-02T01:02:39.569Z","updated_at":"2025-08-26T07:12:32.853Z","avatar_url":"https://github.com/lunarway.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# Release Manager\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/lunarway/release-manager)](https://goreportcard.com/report/github.com/lunarway/release-manager)\n\nGitOps release manager for kubernetes configuration repositories.\n\nThis project is used as an internal project at Lunar and it therefore contains some assumptions on our setup. This includes environment naming (dev, prod). Further it is build around assumptions made by our OSS project `shuttle`, and id's for releases are a combination of branch name, git-sha from source repo, and git-sha from shuttle plan repo. Our initial intent is not to support this as an open source project.\n\nWe will however, have it public available for reference. This might change over time.\n\n# Design\n\nThe release-manager consist of 4 different \"microservices\" with each having a specific responsibility in the pipeline. The applications are basically utilities for moving files around a Git repository.\n\nA simplified overview of all the components involved in the flow can be seen below.\n\n![](docs/gitops_workflow.png)\n\nTo read more about the what each service is responsible for see [Components](#components).\nIn addition to the services we utilize [Jenkins](https://github.com/jenkinsci/jenkins) as a CI server and [flux](https://github.com/fluxcd/flux) as a release operator running inside each cluster.\n\n# Interactions\n\nAs seen on the illustration the main interaction point for developers are their service repository, doing code changes and with the `hamctl` CLI.\n\nBelow are descriptions of the common commands used in day to day activities.\n\n## Promote\n\nThe promotion flows, is a convetion based release process. It can be invoked by `hamctl` as follows:\n\n```\nhamctl promote --service example --env dev\n```\n\nThe convention follows the following flow: `master -\u003e dev -\u003e prod`\nAs seen in the example above, the `example` service will be promoted from the lastest available artifact from `master` to the `dev` environment.\n\nAnother example, is a promotion of an artifact running in, e.g. dev, to the production environment. This can be achieved with the following command:\n\n```\nhamctl promote --service example --env prod\n```\n\nThe above locates what is running in the `dev` environment, and takes the necessary steps to run the same artifact in `prod`.\n\n## Release\n\nThe release flow, is a more liberal release process. There is no conventions in how artifacts move between environments. This makes it suitable for releasing `hotfix`-branches to production or `feature`-branches to a specific environment for testing before merging into `master`.\n\nThe release flow currently consist of two approaches, either the release of the lastest artifact from a given branch, or a specific artifact id.\n\nExample of a release of a feature branch to the `dev` environment:\n\n```\nhamctl release --service example --branch \"feature/new_feature\" --env dev\n```\n\nExample of a release of a specific artifact id to the `prod` environment:\n\n```\nhamctl release --service example --artifact main-0017d995e3-67e9d69164 --env prod\n```\n\n## Status\n\nStatus is a convience flow to display currently released artifact to the three different environments; `dev`,`prod`.\n\n```\n$ hamctl status --service example\n\ndev:\n  Tag: master-1c1508405e-67e9d69164\n  Author: Kasper Nissen\n  Committer: Peter Petersen\n  Message: empty-commit-to-test-flow\n  Date: 2019-04-01 11:14:26 +0200 CEST\n  Link: https://jenkins.example.lunar.app/job/github/job/example-service/job/master/132/display/redirect\n  Vulnerabilities: 0 high, 0 medium, 0 low\n\nprod:\n  Tag: master-8fgh08405e-67e9d69164\n  Author: John John\n  Committer: Hans Hansen\n  Message: some-commit\n  Date: 2019-04-01 11:14:26 +0200 CEST\n  Link: https://jenkins.example.lunar.app/job/github/job/example-service/job/master/132/display/redirect\n  Vulnerabilities: 0 high, 0 medium, 0 low\n```\n\n## Policies\n\nIt is possible to configure policies for releases with `hamctl`'s `policy` command and globally with flags on the `server`.\n\nYou can `list`, `apply` and `delete` policies for a specific service like below.\n\n```\nhamctl policy --service \u003cservice\u003e list\nhamctl policy --service \u003cservice\u003e apply \u003cpolicy\u003e\nhamctl policy --service \u003cservice\u003e delete \u003cpolicy-id\u003e [\u003cpolicy-id\u003e]\n```\n\nSee below for details on how to apply specific policies.\n\nSome policies cannot be applied simultaniously as they semantically does not support each other.\nAn example is an `auto-release` policy releasing a branch not compatible with a `branch-restriction` policy.\nThese cases are validated when applying either of them.\n\n### Auto-release artifacts from branches to environments\n\nAn `auto-release` policy instructs the release manager to deploy new artifacts from a specific branch into an environment.\n\nMultiple policies can be applied for the same branch to different environments, e.g. release `master` artifacts to `dev` and `prod`.\n\nThis is an example of applying an auto-release policy for the product service for the `master` branch and `dev` environment.\n\n```\nhamctl policy --service example apply auto-release --branch master --env dev\n```\n\n### Branch restriction on environments\n\nA `branch-restriction` policy instructs the release manager to only allow artifacts from specific branches to be released to an environment.\nThe `--branch-regex` flag defines a regular expression that is matched against the branch name on every release.\n\nAs an example, the following command applies a branch-restriction policy for the `example` service that only allows the `master` branch to be released to the `prod` environment.\n\n```\nhamctl policy --service example apply branch-restriction --env prod --branch-regex '^master$'\n```\n\nAnother example is to allow only `master` or `hostfix/*` branches in `prod` like this.\n\n```\nhamctl policy --service example apply branch-restriction --env prod --branch-regex '^(master|hotfix\\/.+)$'\n```\n\nIt is not possible to create an auto-release policy for a non-matching branch to an environment that is protected by a branch-restriction policy.\n\nBe aware that the regular expression should be as strict as possible otherwise you might get unexpected results.\nA branch regex like `master` will also allow branch names like `refactor-master-worker`, so make sure to mark the start `^` and end `$` of the string.\n\nThe `server` can also enforce branch restrictions on all managed services by setting the `policy-branch-restrictions` flag.\nIt takes a comma seprated list of `\u003cenvironment\u003e=\u003cbranchRegex\u003e` values.\n\n```\nserver start --policy-branch-restrictions 'production=^master$,dev=^development$'\n```\n\nThey will be visible with `hamctl policy list` but cannot by removed with `hamctl`.\nIt is also not possible to overwrite them with custom policies, e.g. changing branch of a globally restricted environment.\n\n# Releases and policies\n\nRelease files are structured as shown below.\nIn the root are folders for each environment, e.g. `dev`, `prod`.\nThese folders contain a `releases` directory with kubernetes resource definitions of each namespace and their running applications.\nIf an artifact contains a Flux `Kustomization` (`apiVersion: kustomize.toolkit.fluxcd.io/v1` and `kind: Kustomization`) custom resource the release manager moves it into the `clusters` directory tree.\nThis is tailored to support Flux2.\n\nA `policies` directory holds all recorded release policies.\nThese are stored as JSON files for each service.\n\n```\n.\n├── policies\n│   └── \u003cservice\u003e.json\n├── \u003cenvironments\u003e\n├── dev\n│   └── releases\n│       ├── \u003cnamespaces\u003e\n│       └── dev\n│           └── \u003cservice\u003e\n│               ├── artifact.json\n│               ├── 01-configmap.yaml\n│               ├── 02-db-configmap.yaml\n│               ├── 40-deployment.yaml\n│               └── 50-service.yaml\n└── clusters\n    ├── \u003cenvironments\u003e\n    └── dev\n        ├── \u003cnamespaces\u003e\n        └── dev\n            └── \u003cservice\u003e.yaml\n```\n\nWhen running `kubectl apply` files are applied to the cluster alphabetically so the following convention should be used by configuration generators.\n\n```\n00 CRDs\n01-09 configmaps\n10-19 secrets\n20-29 volumes\n30-39 rbac\n40-49 deployments/daemonsets\n50-59 service\n60-69 ingress\n```\n\nResources starting with `00_` will skip resource validation in the Lunar shuttle plans.\n`CustomResourceDefintions` requires custom schemas which are usually not available so they should always start with `00_`.\n\n# Components\n\nThe release-manager consists of four applications.\n\n| Application | Description                                                                                                                                                          |\n| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| artifact    | a simple tool for generating an artifact.json blob with information from the CI pipeline                                                                             |\n| daemon      | a daemon reporting events about cluster component status back to the release-manager server                                                                          |\n| hamctl      | a CLI client for interacting with the release-manager server                                                                                                         |\n| server      | the API-server where clients (hamtcl) connects to, and daemon reports events to. It further implements different flows, e.g., promote a release, release an artifact |\n\n## Artifact\n\n`artifact` is used to generate, what we refer to as artifacts.\nThese are a `json` file containing relevant information from the CI flow.\nThe id's of the artifacts, are composed of `\u003cbranch-name\u003e-\u003capplication-git-sha\u003e-\u003cshuttle-plan-git-sha\u003e`.\n\nWe use [shuttle](https://github.com/lunarway/shuttle) plans to centralize our CI pipeline definitions, which is why we include the version of the plan in the artifact id.\n\nHere is a redacted example of a generated artifact specification.\n\n```json\n{\n  \"id\": \"dev-0017d995e3-67e9d69164\",\n  \"application\": {\n    \"sha\": \"0017d995e32e3d1998395d971b969bcf682d2085\",\n    \"message\": \"fix something\",\n    \"name\": \"example-service\",\n    ...\n    \"url\": \"https://github.com/lunarway/example-service/commits/0017d995e32e3d1998395d971b969bcf682d2085\",\n    \"provider\": \"GitHub\"\n  },\n  \"ci\": {\n    \"jobUrl\": \"https://jenkins.example.lunar.app/job/github/job/example-service/job/dev/84/display/redirect\",\n    \"start\": \"2019-03-29T13:47:15.259380775+01:00\",\n    \"end\": \"2019-03-29T13:49:57.686299407+01:00\"\n  },\n  \"shuttle\": {\n    \"plan\": {\n      \"message\": \"Support-new-feature\",\n      \"url\": \"git://git@github.com:lunarway/lw-shuttle-go-plan.git\"\n    }\n  },\n  \"stages\": [\n    {\n      \"id\": \"build\",\n      \"name\": \"Build\",\n      \"data\": {\n        \"dockerVersion\": \"18.09.3\",\n        \"image\": \"quay.io/lunarway/example\",\n        \"tag\": \"dev-0017d995e3-67e9d69164\"\n      }\n    }\n  ]\n}\n```\n\n## hamctl\n\n`hamctl` is a CLI for interacting with the release-manager server.\nExamples of commands are `hamctl release` or `hamctl status`.\n\nSee [Interactions](#interactions) for more examples.\n\nIt uses a oauth2 authentication model for interacting with the server.\nSpecifically the Device Authorization flow.\n\nThis must be set up using the environment variables:\n\n`HAMCTL_OAUTH_IDP_URL` pointing to your IdP where there must be an endpoint `{idp-url}/v1/token` for exchanging tokens.\n\n`HAMCTL_OAUTH_CLIENT_ID` which is the oauth2 client id.\n\n`hamctl` will automatically initiate a login if you do not have a valid token on your system.\nYou can opt out of this behaviour by setting the environement variable `HAMCTL_OAUTH_AUTO_LOGIN=false`.\n\n### Completions\n\nShell completions are available with the command `completion`.\nThe following commands will add completions to the current shell in either bash or zsh.\n\n```\nsource \u003c(hamctl completion bash)\nsource \u003c(hamctl completion zsh)\n```\n\nFor a more detailed installation instruction see the help output.\n\n```\nhamctl completion --help\n```\n\n## daemon\n\nThe `daemon` is an agent running in each of the kubernetes clusters and reports state changes in the environment back to the release-manager.\n`daemon` needs access to the kubernetes API server, and can be configured using a `ServiceAccount`.\n\n`daemon` uses a token-based authentication model for interacting with the release-manager.\nThis token can be set using the command-line argument `--auth-token` or the ENV variable: `DAEMON_AUTH_TOKEN`\n\n## Server\n\nThe server is responsible for all the operations related to releasing new versions.\n`hamctl` and `artifact` communicates with it over HTTP to initiate releases, register new artifacts etc.\n\nIn its simplest form it is responsible for moving files around a Git repository based on the commands it receives, eg. release artifact.\n\n### Notifications\n\nWhen releasing applications the server will notify different upstream services along with outputting an identifiable log useful for log aggregation statistics.\n\n```\ninfo  command/start.go:145  Release [dev]: verification (master-e8da185c2c-06249f1a78) by Bjørn Sørensen, author Bjørn Sørensen\n```\n\nA Slack message is pushed to a `#releases-\u003cenv\u003e` Slack channel.\n\n![](docs/slack_release_message.png)\n\nGrafana is annotated with release metadata and tag `deployment` useful for plotting on graphs to see when new releases are rolled out.\n\n![](docs/grafana_annotation.png)\n\nIf the artifact provider is GitHub and a GitHub API token is provided (`--github-api-token`) the application source repository is tagged with `\u003cenv\u003e` on the released Git SHA.\n\n![](docs/github_tag.png)\n\n### Tracing support\n\nThe server collects [Jaeger](https://www.jaegertracing.io/) spans. This is enabled by default and reported as service `release-manager`.\nThe jaeger configuration can be customized with available [environment variables](https://github.com/jaegertracing/jaeger-client-go#environment-variables).\n\nFor local development a jaeger all-in-one instance can be created with Docker running `make jaeger`.\nThe Jaeger UI will be available on [`localhost:16686`](http://localhost:16686).\n\nTo disable collection set `JAEGER_DISABLED=true`.\n\n# Storage\n\nMultiple entities are stored in different storage layers to allow the release manager to work.\n\n## Artifacts\n\nArtifacts are stored in an AWS S3 bucket.\nThey are stored as `zip` files with keys from the service name and artifact id.\n\n```\n.\n├── \u003cservice\u003e\n│  └── \u003cartifact-id\u003e\n└── example\n    └── master-sha1234-plan1234\n```\n\n## Policies\n\nPolicies are stored in the Git repository along with all releases.\nEach service policy is a JSON file in the `policies/\u003cservice\u003e.json` path.\n\n```json\n{\n  \"service\": \"example\",\n  \"autoReleases\": [\n    {\n      \"id\": \"auto-release-master-dev\",\n      \"branch\": \"master\",\n      \"environment\": \"dev\"\n    }\n  ]\n}\n```\n\n# Installation\n\nAll the applications are cross compiled to Linux and MacOS and available in the [Releases](https://github.com/lunarway/release-manager/releases) page.\nThe server and daemon are also available as Docker images at [quay.io/lunarway/release-manager](quay.io/lunarway/release-manager) and [quay.io/lunarway/release-daemon](quay.io/lunarway/release-daemon).\n\nUsually you will release the server and daemon with kubernetes `Deployment` resources and distribute the `hamctl` CLI to developers.\n`artifact` should be distributed to the Jenkins CI server and used in the pipelines.\n\n## Access to the config repository\n\nThe release manager server needs read/write permissions to the config repo.\n\nTo create a secret that the release manager can consume: (expects that the filename is identity)\n\n```\nkubectl create secret generic release-manager-git-deploy --from-file=identity=key\n```\n\nThis secret should be mounted to `/etc/release-manager/ssh`\n\n# Development\n\nThe `Makefile` exposes targets for building, testing and deploying the release manager and its CLIs.\nSee it for details.\n\nThe most common operations are build and tests.\n\n```\n$ make build\ngo build -o dist/hamctl ./cmd/hamctl\ngo build -o dist/server ./cmd/server\ngo build -o dist/artifact ./cmd/artifact\n\n$ make build_server\ngo build -o dist/server ./cmd/server\n\n$ make test\ngo test -v ./...\n```\n\n## e2e setup\n\nTo help development it is possible to use the e2e setup.\n\nThis setup is based a kubernetes cluster managed by `kind`. The following resources is setup up\n\n| Name              | Description                                                                                                                                                                                                                                                                                                  |\n| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `source-git-repo` | A local git repository in `e2e-test/source-git-repo` that is used as the config repository.                                                                                                                                                                                                                  |\n| `fluxd`           | The fluxd service inside the k8s cluster, which is connected to the `source-git-repo`. It is polling the repo for changes every 5s, so it triggers as soon as a commit is done in `source-git-repo`, like a webhook from github normally would. Additionally fluxd is setup to `--connect` to release-daemon |\n| `release-daemon`  | A locally built binary of the release-daemon, but running inside the k8s cluster. The binary is mounted from local `e2e-test/binaries` for quick rebuild, so the pod can just be restarted while developing. This is done using the **rebuild** or **watch** actions.                                        |\n| `release-server`  | A locally built binary of the release-daemon, that is running in the same manner as the `release-daemon`                                                                                                                                                                                                     |\n| `rabbitmq`        | A simply setup rabbitmq server for the release-manager                                                                                                                                                                                                                                                       |\n\nTo use the e2e setup there are the following actions supported:\n\n| Action                   | Command                          | Description                                                                                          |\n| ------------------------ | -------------------------------- | ---------------------------------------------------------------------------------------------------- |\n| Start e2e setup          | `make e2e-setup`                 | Start and initiate kind and e2e setup                                                                |\n| Rebuild manager          | `make e2e-rebuild-local-manager` | Rebuild the manager and restart pod in e2e cluster                                                   |\n| Rebuild daemon           | `make e2e-rebuild-local-daemon`  | Like \"Rebuild manager\" but for the daemon                                                            |\n| Watch manager            | `make e2e-rebuild-local-manager` | Watch source code changes and rebuild the manager and restart pod in e2e cluster. Requires `nodemon` |\n| Watch daemon             | `make e2e-rebuild-local-daemon`  | Like \"Watch manager\" but for the daemon                                                              |\n| Do dummy release         | `make e2e-do-release`            | Do a release in git repo to trigger fluxd change                                                     |\n| Do another dummy release | `make e2e-do-another-release`    | Do another kind of release in git repo to trigger fluxd change                                       |\n| Stop e2e setup           | `make e2e-teardown`              | Stop and cleanup the e2e setup                                                                       |\n\n## Releasing\n\nThis project is configured with `goreleaser` and releases all 4 applications at once.\nPush a new tag to the main branch and GitHub actions will publish a new release and create the changelog.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flunarway%2Frelease-manager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flunarway%2Frelease-manager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flunarway%2Frelease-manager/lists"}