From e1972bfcf2789798a340cb63cb61cfbd927b9856 Mon Sep 17 00:00:00 2001 From: italolelis Date: Fri, 10 Jan 2020 11:25:11 +0100 Subject: [PATCH 01/33] Add new arguments --- action.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/action.yml b/action.yml index 81dae8c8..8beb00f0 100644 --- a/action.yml +++ b/action.yml @@ -1,6 +1,6 @@ -name: Deliverybot Helm Action +name: Helm Action description: Deploys a helm chart -author: deliverybot +author: lykon icon: box color: gray-dark inputs: @@ -27,6 +27,14 @@ inputs: JSON encoded map. version: description: Version of the app, usually commit sha works here. + repo: + description: Helm chart repository to be added. + repo_alias: + description: Helm repository alias that will be used. + repo_username: + description: Helm repository username if authentication is needed. + repo_password: + description: Helm repository password if authentication is needed. runs: using: docker image: Dockerfile From 14bdb1b71335d38b9e9a92dd23bc05b77273fe4b Mon Sep 17 00:00:00 2001 From: italolelis Date: Fri, 10 Jan 2020 11:25:19 +0100 Subject: [PATCH 02/33] Upgrade helm3 version --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ea1aa4fb..0fc91b08 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM alpine:3.10.2 ENV BASE_URL="https://get.helm.sh" ENV HELM_2_FILE="helm-v2.16.1-linux-amd64.tar.gz" -ENV HELM_3_FILE="helm-v3.0.0-linux-amd64.tar.gz" +ENV HELM_3_FILE="helm-v3.0.2-linux-amd64.tar.gz" RUN apk add --no-cache ca-certificates jq curl bash nodejs && \ # Install helm version 2: From 63da27697d50463462babdf3e0e38e4edf478f12 Mon Sep 17 00:00:00 2001 From: italolelis Date: Fri, 10 Jan 2020 11:25:28 +0100 Subject: [PATCH 03/33] Add repo add capabilities --- index.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/index.js b/index.js index f8560902..27c39558 100644 --- a/index.js +++ b/index.js @@ -165,6 +165,10 @@ async function run() { const removeCanary = getInput("remove_canary"); const helm = getInput("helm") || "helm"; const timeout = getInput("timeout"); + const repo = getInput("repo"); + const repoAlias = getInput("repo_alias"); + const repoUsername = getInput("repo_username"); + const repoPassword = getInput("repo_password"); const dryRun = core.getInput("dry-run"); const secrets = getSecrets(core.getInput("secrets")); @@ -182,6 +186,10 @@ async function run() { core.debug(`param: valueFiles = "${JSON.stringify(valueFiles)}"`); core.debug(`param: removeCanary = ${removeCanary}`); core.debug(`param: timeout = "${timeout}"`); + core.debug(`param: repo = "${repo}"`); + core.debug(`param: repoAlias = "${repoAlias}"`); + core.debug(`param: repoUsername = "${repoUsername}"`); + core.debug(`param: repoPassword = "${repoPassword}"`); // Setup command options and arguments. const opts = { env: { @@ -234,6 +242,26 @@ async function run() { }); } + if (repo !== "") { + if (repoAlias === "") { + core.setFailed("repo alias is required when you are setting a repository"); + await status("failure"); + } + + core.debug(`adding custom repository ${repo} with alias ${repoAlias}`); + const repoAddArgs = [ + "repo", + "add", + repoAlias, + repo, + ] + + if (repoUsername) repoAddArgs.push(`--username=${repoUsername}`); + if (repoPassword) repoAddArgs.push(`--password=${repoPassword}`); + + await exec.exec(helm, repoAddArgs); + } + // Actually execute the deployment here. if (task === "remove") { await exec.exec(helm, deleteCmd(helm, namespace, release), { From 6b6b0e1f93a29856f989305da9f5887e4ba6b2db Mon Sep 17 00:00:00 2001 From: italolelis Date: Fri, 10 Jan 2020 11:28:12 +0100 Subject: [PATCH 04/33] Update readme with helm repo add instructions --- README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/README.md b/README.md index ddd209c5..81578939 100644 --- a/README.md +++ b/README.md @@ -150,3 +150,34 @@ jobs: env: KUBECONFIG_FILE: '${{ secrets.KUBECONFIG }}' ``` + +## Example add custom repository + +Sometime you may want to add a custom repository, like [chartmuseum](https://github.com/helm/chartmuseum). For th + +```yaml +# .github/workflows/pr-cleanup.yml +name: PRCleanup +on: + pull_request: + types: [closed] + +jobs: + deployment: + runs-on: 'ubuntu-latest' + steps: + - name: 'Deploy' + uses: 'deliverybot/helm@v1' + with: + release: 'nginx' + namespace: 'default' + chart: 'chartmuseum/app' + token: '${{ github.token }}' + repo: 'http://chartmuseum.example.com' + repo_alias: chartmuseum + repo_username: ${{ secrets.CHARTMUSEUM_USERNAME }} + repo_password: ${{ secrets.CHARTMUSEUM_PASSWORD }} + env: + KUBECONFIG_FILE: '${{ secrets.KUBECONFIG }}' +``` + From ff8c8782a65919c0f133cfa33f83accb867e2c5d Mon Sep 17 00:00:00 2001 From: italolelis Date: Fri, 10 Jan 2020 11:37:25 +0100 Subject: [PATCH 05/33] Update action keys --- action.yml | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/action.yml b/action.yml index 8beb00f0..7c024a71 100644 --- a/action.yml +++ b/action.yml @@ -1,40 +1,54 @@ -name: Helm Action -description: Deploys a helm chart +name: Helm Deploy +description: Deploys a helm chart to Kubernetes author: lykon -icon: box -color: gray-dark +branding: + icon: anchor + color: gray-dark inputs: release: - description: Helm release name. Will be combined with track if set. (required) + description: Helm release name. Will be combined with track if set. + required: true namespace: - description: Kubernetes namespace name. (required) + description: Kubernetes namespace name. + required: true chart: description: Helm chart path. If set to "app" this will use the built in helm - chart found in this repository. (required) + chart found in this repository. + required: true values: description: Helm chart values, expected to be a YAML or JSON string. + required: false dry-run: description: Task name. If the task is "remove" it will remove the configured helm release. + required: false token: description: Github repository token. If included and the event is a deployment the deployment_status event will be fired. + required: false value-files: description: Additional value files to apply to the helm chart. Expects JSON encoded array or a string. + required: false secrets: description: Secret variables to include in value file interpolation. Expects JSON encoded map. + required: false version: description: Version of the app, usually commit sha works here. + required: false repo: description: Helm chart repository to be added. + required: false repo_alias: description: Helm repository alias that will be used. + required: false repo_username: description: Helm repository username if authentication is needed. + required: false repo_password: description: Helm repository password if authentication is needed. + required: false runs: using: docker image: Dockerfile From 268dbf34fce3473e13e92b09cb75a28b2ba288e3 Mon Sep 17 00:00:00 2001 From: italolelis Date: Fri, 10 Jan 2020 11:37:30 +0100 Subject: [PATCH 06/33] Add missing inputs --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 81578939..32340c4e 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,10 @@ payload if the action was triggered by a deployment. - `helm`: Helm binary to execute, one of: [`helm`, `helm3`]. - `version`: Version of the app, usually commit sha works here. - `timeout`: specify a timeout for helm deployment +- `repo`: Helm chart repository to be added. +- `repo_alias`: Helm repository alias that will be used. +- `repo_username`: Helm repository username if authentication is needed. +- `repo_password`: Helm repository password if authentication is needed. Additional parameters: If the action is being triggered by a deployment event and the `task` parameter in the deployment event is set to `"remove"` then this From 5fc03299cef082eea83ed4f19e0976629b45480e Mon Sep 17 00:00:00 2001 From: italolelis Date: Fri, 10 Jan 2020 13:05:36 +0100 Subject: [PATCH 07/33] Replace _ to - --- README.md | 12 ++++++------ action.yml | 6 +++--- index.js | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 32340c4e..ee4cdefc 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,9 @@ payload if the action was triggered by a deployment. - `version`: Version of the app, usually commit sha works here. - `timeout`: specify a timeout for helm deployment - `repo`: Helm chart repository to be added. -- `repo_alias`: Helm repository alias that will be used. -- `repo_username`: Helm repository username if authentication is needed. -- `repo_password`: Helm repository password if authentication is needed. +- `repo-alias`: Helm repository alias that will be used. +- `repo-username`: Helm repository username if authentication is needed. +- `repo-password`: Helm repository password if authentication is needed. Additional parameters: If the action is being triggered by a deployment event and the `task` parameter in the deployment event is set to `"remove"` then this @@ -178,9 +178,9 @@ jobs: chart: 'chartmuseum/app' token: '${{ github.token }}' repo: 'http://chartmuseum.example.com' - repo_alias: chartmuseum - repo_username: ${{ secrets.CHARTMUSEUM_USERNAME }} - repo_password: ${{ secrets.CHARTMUSEUM_PASSWORD }} + repo-alias: chartmuseum + repo-username: ${{ secrets.CHARTMUSEUM_USERNAME }} + repo-password: ${{ secrets.CHARTMUSEUM_PASSWORD }} env: KUBECONFIG_FILE: '${{ secrets.KUBECONFIG }}' ``` diff --git a/action.yml b/action.yml index 7c024a71..748cff29 100644 --- a/action.yml +++ b/action.yml @@ -40,13 +40,13 @@ inputs: repo: description: Helm chart repository to be added. required: false - repo_alias: + repo-alias: description: Helm repository alias that will be used. required: false - repo_username: + repo-username: description: Helm repository username if authentication is needed. required: false - repo_password: + repo-password: description: Helm repository password if authentication is needed. required: false runs: diff --git a/index.js b/index.js index 27c39558..16b2b46d 100644 --- a/index.js +++ b/index.js @@ -166,9 +166,9 @@ async function run() { const helm = getInput("helm") || "helm"; const timeout = getInput("timeout"); const repo = getInput("repo"); - const repoAlias = getInput("repo_alias"); - const repoUsername = getInput("repo_username"); - const repoPassword = getInput("repo_password"); + const repoAlias = getInput("repo-alias"); + const repoUsername = getInput("repo-username"); + const repoPassword = getInput("repo-password"); const dryRun = core.getInput("dry-run"); const secrets = getSecrets(core.getInput("secrets")); From 7613a57db30b79e1e712d72bc917efee491a35b3 Mon Sep 17 00:00:00 2001 From: italolelis Date: Fri, 10 Jan 2020 14:10:53 +0100 Subject: [PATCH 08/33] List repos to debug issue --- index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/index.js b/index.js index 16b2b46d..20cb0f26 100644 --- a/index.js +++ b/index.js @@ -260,6 +260,7 @@ async function run() { if (repoPassword) repoAddArgs.push(`--password=${repoPassword}`); await exec.exec(helm, repoAddArgs); + await exec.exec(helm, "helm repo list"); } // Actually execute the deployment here. From 29af0fe11355a661f67526a66d349d6ae81d678e Mon Sep 17 00:00:00 2001 From: italolelis Date: Fri, 10 Jan 2020 14:18:01 +0100 Subject: [PATCH 09/33] Remove helm keyword --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 20cb0f26..c5fa75f1 100644 --- a/index.js +++ b/index.js @@ -260,7 +260,7 @@ async function run() { if (repoPassword) repoAddArgs.push(`--password=${repoPassword}`); await exec.exec(helm, repoAddArgs); - await exec.exec(helm, "helm repo list"); + await exec.exec(helm, "repo list"); } // Actually execute the deployment here. From bccdbf1556e65c8580d3cfd9b8a8393d016b6463 Mon Sep 17 00:00:00 2001 From: italolelis Date: Fri, 10 Jan 2020 14:26:14 +0100 Subject: [PATCH 10/33] Change argument type --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index c5fa75f1..8d432da2 100644 --- a/index.js +++ b/index.js @@ -260,7 +260,7 @@ async function run() { if (repoPassword) repoAddArgs.push(`--password=${repoPassword}`); await exec.exec(helm, repoAddArgs); - await exec.exec(helm, "repo list"); + await exec.exec(helm, ["repo", "list"]); } // Actually execute the deployment here. From 901970f54096dac274af959ea88dc286570e67c5 Mon Sep 17 00:00:00 2001 From: italolelis Date: Fri, 10 Jan 2020 14:37:35 +0100 Subject: [PATCH 11/33] Add repo update --- index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/index.js b/index.js index 8d432da2..000c1649 100644 --- a/index.js +++ b/index.js @@ -270,6 +270,7 @@ async function run() { ignoreReturnCode: true }); } else { + await exec.exec(helm, ["repo", "update"]); await exec.exec(helm, args, opts); } From d9797154d23112ecd3313dc3eec71b88717a3130 Mon Sep 17 00:00:00 2001 From: italolelis Date: Fri, 10 Jan 2020 14:51:55 +0100 Subject: [PATCH 12/33] Add in the same commenda --- index.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 000c1649..d45a7ef1 100644 --- a/index.js +++ b/index.js @@ -258,9 +258,11 @@ async function run() { if (repoUsername) repoAddArgs.push(`--username=${repoUsername}`); if (repoPassword) repoAddArgs.push(`--password=${repoPassword}`); + + repoAddArgs.push("&&"); + repoAddArgs.push(helm); - await exec.exec(helm, repoAddArgs); - await exec.exec(helm, ["repo", "list"]); + args.unshift(repoAddArgs); } // Actually execute the deployment here. @@ -270,7 +272,6 @@ async function run() { ignoreReturnCode: true }); } else { - await exec.exec(helm, ["repo", "update"]); await exec.exec(helm, args, opts); } From c272bc909cf79a2326b9f4d51d1349df7f707b09 Mon Sep 17 00:00:00 2001 From: italolelis Date: Fri, 10 Jan 2020 15:05:54 +0100 Subject: [PATCH 13/33] Unpack array --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index d45a7ef1..f874a7d6 100644 --- a/index.js +++ b/index.js @@ -262,7 +262,7 @@ async function run() { repoAddArgs.push("&&"); repoAddArgs.push(helm); - args.unshift(repoAddArgs); + args = repoAddArgs.concat(args) } // Actually execute the deployment here. From 3c9ab6cfa613d563bc382ff70f9a19f7a3e8a8c4 Mon Sep 17 00:00:00 2001 From: italolelis Date: Fri, 10 Jan 2020 15:12:56 +0100 Subject: [PATCH 14/33] Change from const to let --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index f874a7d6..d2cf2727 100644 --- a/index.js +++ b/index.js @@ -195,7 +195,7 @@ async function run() { const opts = { env: { KUBECONFIG: process.env.KUBECONFIG, }}; - const args = [ + let args = [ "upgrade", release, chart, From ea3f24e96b4ec4a8190c937c5f0c80113d60d21e Mon Sep 17 00:00:00 2001 From: italolelis Date: Fri, 10 Jan 2020 17:06:11 +0100 Subject: [PATCH 15/33] try semi colon --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index d2cf2727..49921161 100644 --- a/index.js +++ b/index.js @@ -259,7 +259,7 @@ async function run() { if (repoUsername) repoAddArgs.push(`--username=${repoUsername}`); if (repoPassword) repoAddArgs.push(`--password=${repoPassword}`); - repoAddArgs.push("&&"); + repoAddArgs.push(";"); repoAddArgs.push(helm); args = repoAddArgs.concat(args) From 8d177003551f2c9f2cd7fcc5c3cc61833985bd98 Mon Sep 17 00:00:00 2001 From: mpraski Date: Mon, 25 Jan 2021 16:11:01 +0100 Subject: [PATCH 16/33] First add repo, then run deployment --- index.js | 282 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 153 insertions(+), 129 deletions(-) diff --git a/index.js b/index.js index 476dfb6d..3dd24a85 100644 --- a/index.js +++ b/index.js @@ -145,150 +145,174 @@ function deleteCmd(helm, namespace, release) { return ["delete", "--purge", release]; } -/** - * Run executes the helm deployment. +/* + * Optionally add a helm repository */ -async function run() { - try { - const context = github.context; - await status("pending"); +async function addRepo(helm) { + const repo = getInput("repo"); + const repoAlias = getInput("repo-alias"); + const repoUsername = getInput("repo-username"); + const repoPassword = getInput("repo-password"); - const track = getInput("track") || "stable"; - const appName = getInput("release", required); - const release = releaseName(appName, track); - const namespace = getInput("namespace", required); - const chart = chartName(getInput("chart", required)); - const chartVersion = getInput("chart_version"); - const values = getValues(getInput("values")); - const task = getInput("task"); - const version = getInput("version"); - const valueFiles = getValueFiles(getInput("value_files")); - const removeCanary = getInput("remove_canary"); - const helm = getInput("helm") || "helm"; - const timeout = getInput("timeout"); - const repo = getInput("repo"); - const repoAlias = getInput("repo-alias"); - const repoUsername = getInput("repo-username"); - const repoPassword = getInput("repo-password"); - const dryRun = core.getInput("dry-run"); - const secrets = getSecrets(core.getInput("secrets")); - const atomic = getInput("atomic") || true; - - core.debug(`param: track = "${track}"`); - core.debug(`param: release = "${release}"`); - core.debug(`param: appName = "${appName}"`); - core.debug(`param: namespace = "${namespace}"`); - core.debug(`param: chart = "${chart}"`); - core.debug(`param: chart_version = "${chartVersion}"`); - core.debug(`param: values = "${values}"`); - core.debug(`param: dryRun = "${dryRun}"`); - core.debug(`param: task = "${task}"`); - core.debug(`param: version = "${version}"`); - core.debug(`param: secrets = "${JSON.stringify(secrets)}"`); - core.debug(`param: valueFiles = "${JSON.stringify(valueFiles)}"`); - core.debug(`param: removeCanary = ${removeCanary}`); - core.debug(`param: timeout = "${timeout}"`); - core.debug(`param: atomic = "${atomic}"`); - core.debug(`param: repo = "${repo}"`); - core.debug(`param: repoAlias = "${repoAlias}"`); - core.debug(`param: repoUsername = "${repoUsername}"`); - core.debug(`param: repoPassword = "${repoPassword}"`); - - // Setup command options and arguments. - let args = [ - "upgrade", - release, - chart, - "--install", - "--wait", - `--namespace=${namespace}`, - ]; - - // Per https://helm.sh/docs/faq/#xdg-base-directory-support - if (helm === "helm3") { - process.env.XDG_DATA_HOME = "/root/.helm/" - process.env.XDG_CACHE_HOME = "/root/.helm/" - process.env.XDG_CONFIG_HOME = "/root/.helm/" - } else { - process.env.HELM_HOME = "/root/.helm/" - } + core.debug(`param: repo = "${repo}"`); + core.debug(`param: repoAlias = "${repoAlias}"`); + core.debug(`param: repoUsername = "${repoUsername}"`); + core.debug(`param: repoPassword = "${repoPassword}"`); - if (dryRun) args.push("--dry-run"); - if (appName) args.push(`--set=app.name=${appName}`); - if (version) args.push(`--set=app.version=${version}`); - if (chartVersion) args.push(`--version=${chartVersion}`); - if (timeout) args.push(`--timeout=${timeout}`); - valueFiles.forEach(f => args.push(`--values=${f}`)); - args.push("--values=./values.yml"); - - // Special behaviour is triggered if the track is labelled 'canary'. The - // service and ingress resources are disabled. Access to the canary - // deployments can be routed via the main stable service resource. - if (track === "canary") { - args.push("--set=service.enabled=false", "--set=ingress.enabled=false"); + if (repo !== "") { + if (repoAlias === "") { + core.setFailed("repo alias is required when you are setting a repository"); + return status("failure"); } - // If true upgrade process rolls back changes made in case of failed upgrade. - if (atomic === true) { - args.push("--atomic"); - } + core.debug(`adding custom repository ${repo} with alias ${repoAlias}`); - // Setup necessary files. - if (process.env.KUBECONFIG_FILE) { - process.env.KUBECONFIG = "./kubeconfig.yml"; - await writeFile(process.env.KUBECONFIG, process.env.KUBECONFIG_FILE); - } - await writeFile("./values.yml", values); + const args = [ + "repo", + "add", + repoAlias, + repo, + ] + + if (repoUsername) args.push(`--username=${repoUsername}`); + if (repoPassword) args.push(`--password=${repoPassword}`); + + return exec.exec(helm, args); + } + + return Promise.resolve() +} + +/* + * Deploy the release + */ +async function deploy(helm) { + const context = github.context; + + const track = getInput("track") || "stable"; + const appName = getInput("release", required); + const release = releaseName(appName, track); + const namespace = getInput("namespace", required); + const chart = chartName(getInput("chart", required)); + const chartVersion = getInput("chart_version"); + const values = getValues(getInput("values")); + const task = getInput("task"); + const version = getInput("version"); + const valueFiles = getValueFiles(getInput("value_files")); + const removeCanary = getInput("remove_canary"); + const timeout = getInput("timeout"); + const dryRun = core.getInput("dry-run"); + const secrets = getSecrets(core.getInput("secrets")); + const atomic = getInput("atomic") || true; + + core.debug(`param: track = "${track}"`); + core.debug(`param: release = "${release}"`); + core.debug(`param: appName = "${appName}"`); + core.debug(`param: namespace = "${namespace}"`); + core.debug(`param: chart = "${chart}"`); + core.debug(`param: chart_version = "${chartVersion}"`); + core.debug(`param: values = "${values}"`); + core.debug(`param: dryRun = "${dryRun}"`); + core.debug(`param: task = "${task}"`); + core.debug(`param: version = "${version}"`); + core.debug(`param: secrets = "${JSON.stringify(secrets)}"`); + core.debug(`param: valueFiles = "${JSON.stringify(valueFiles)}"`); + core.debug(`param: removeCanary = ${removeCanary}`); + core.debug(`param: timeout = "${timeout}"`); + core.debug(`param: atomic = "${atomic}"`); + + // Setup command options and arguments. + let args = [ + "upgrade", + release, + chart, + "--install", + "--wait", + `--namespace=${namespace}`, + ]; + + // Per https://helm.sh/docs/faq/#xdg-base-directory-support + if (helm === "helm3") { + process.env.XDG_DATA_HOME = "/root/.helm/" + process.env.XDG_CACHE_HOME = "/root/.helm/" + process.env.XDG_CONFIG_HOME = "/root/.helm/" + } else { + process.env.HELM_HOME = "/root/.helm/" + } + + if (dryRun) args.push("--dry-run"); + if (appName) args.push(`--set=app.name=${appName}`); + if (version) args.push(`--set=app.version=${version}`); + if (chartVersion) args.push(`--version=${chartVersion}`); + if (timeout) args.push(`--timeout=${timeout}`); + + valueFiles.forEach(f => args.push(`--values=${f}`)); - core.debug(`env: KUBECONFIG="${process.env.KUBECONFIG}"`); + args.push("--values=./values.yml"); - // Render value files using github variables. - await renderFiles(valueFiles.concat(["./values.yml"]), { - secrets, - deployment: context.payload.deployment, + // Special behaviour is triggered if the track is labelled 'canary'. The + // service and ingress resources are disabled. Access to the canary + // deployments can be routed via the main stable service resource. + if (track === "canary") { + args.push("--set=service.enabled=false", "--set=ingress.enabled=false"); + } + + // If true upgrade process rolls back changes made in case of failed upgrade. + if (atomic === true) { + args.push("--atomic"); + } + + // Setup necessary files. + if (process.env.KUBECONFIG_FILE) { + process.env.KUBECONFIG = "./kubeconfig.yml"; + await writeFile(process.env.KUBECONFIG, process.env.KUBECONFIG_FILE); + } + + await writeFile("./values.yml", values); + + core.debug(`env: KUBECONFIG="${process.env.KUBECONFIG}"`); + + // Render value files using github variables. + await renderFiles(valueFiles.concat(["./values.yml"]), { + secrets, + deployment: context.payload.deployment, + }); + + // Remove the canary deployment before continuing. + if (removeCanary) { + core.debug(`removing canary ${appName}-canary`); + await exec.exec(helm, deleteCmd(helm, namespace, `${appName}-canary`), { + ignoreReturnCode: true }); + } - // Remove the canary deployment before continuing. - if (removeCanary) { - core.debug(`removing canary ${appName}-canary`); - await exec.exec(helm, deleteCmd(helm, namespace, `${appName}-canary`), { - ignoreReturnCode: true - }); - } + // Actually execute the deployment here. + if (task === "remove") { + return exec.exec(helm, deleteCmd(helm, namespace, release), { + ignoreReturnCode: true + }); + } - if (repo !== "") { - if (repoAlias === "") { - core.setFailed("repo alias is required when you are setting a repository"); - await status("failure"); - } + return exec.exec(helm, args); +} - core.debug(`adding custom repository ${repo} with alias ${repoAlias}`); - const repoAddArgs = [ - "repo", - "add", - repoAlias, - repo, - ] - - if (repoUsername) repoAddArgs.push(`--username=${repoUsername}`); - if (repoPassword) repoAddArgs.push(`--password=${repoPassword}`); - - repoAddArgs.push(";"); - repoAddArgs.push(helm); - - args = repoAddArgs.concat(args) - } +/** + * Run executes the helm deployment. + */ +async function run() { + const commands = [addRepo, deploy] + + try { + await status("pending"); + + const helm = getInput("helm") || "helm"; + core.debug(`param: helm = "${helm}"`); - // Actually execute the deployment here. - if (task === "remove") { - await exec.exec(helm, deleteCmd(helm, namespace, release), { - ignoreReturnCode: true - }); - } else { - await exec.exec(helm, args); + for(const command of commands) { + await command(helm); } - await status(task === "remove" ? "inactive" : "success"); + await status("success"); } catch (error) { core.error(error); core.setFailed(error.message); From bf37844b14476488a474ada74cbf251a245f4fb5 Mon Sep 17 00:00:00 2001 From: mpraski Date: Mon, 25 Jan 2021 16:14:29 +0100 Subject: [PATCH 17/33] Use exception to signal failure --- index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/index.js b/index.js index 3dd24a85..09478025 100644 --- a/index.js +++ b/index.js @@ -161,8 +161,7 @@ async function addRepo(helm) { if (repo !== "") { if (repoAlias === "") { - core.setFailed("repo alias is required when you are setting a repository"); - return status("failure"); + throw new Error("repo alias is required when you are setting a repository"); } core.debug(`adding custom repository ${repo} with alias ${repoAlias}`); From 66e7ea1f1370485a9763892d90fbc3957efecd9e Mon Sep 17 00:00:00 2001 From: mpraski Date: Mon, 25 Jan 2021 16:21:46 +0100 Subject: [PATCH 18/33] Default to helm3 --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 09478025..e0498f85 100644 --- a/index.js +++ b/index.js @@ -304,7 +304,7 @@ async function run() { try { await status("pending"); - const helm = getInput("helm") || "helm"; + const helm = getInput("helm") || "helm3"; core.debug(`param: helm = "${helm}"`); for(const command of commands) { From eef52034b40ddb2590128dbdb8b24c10513666d0 Mon Sep 17 00:00:00 2001 From: mpraski Date: Mon, 25 Jan 2021 16:23:45 +0100 Subject: [PATCH 19/33] Default options for helm3 --- index.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index e0498f85..82a6ef23 100644 --- a/index.js +++ b/index.js @@ -230,14 +230,9 @@ async function deploy(helm) { `--namespace=${namespace}`, ]; - // Per https://helm.sh/docs/faq/#xdg-base-directory-support - if (helm === "helm3") { - process.env.XDG_DATA_HOME = "/root/.helm/" - process.env.XDG_CACHE_HOME = "/root/.helm/" - process.env.XDG_CONFIG_HOME = "/root/.helm/" - } else { - process.env.HELM_HOME = "/root/.helm/" - } + process.env.XDG_DATA_HOME = "/root/.helm/" + process.env.XDG_CACHE_HOME = "/root/.helm/" + process.env.XDG_CONFIG_HOME = "/root/.helm/" if (dryRun) args.push("--dry-run"); if (appName) args.push(`--set=app.name=${appName}`); From c4bff616a59099c734cf977ebb8d697629ef531e Mon Sep 17 00:00:00 2001 From: mpraski Date: Mon, 25 Jan 2021 17:42:27 +0100 Subject: [PATCH 20/33] Update repo cache after adding --- index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 82a6ef23..30cf8c14 100644 --- a/index.js +++ b/index.js @@ -176,7 +176,8 @@ async function addRepo(helm) { if (repoUsername) args.push(`--username=${repoUsername}`); if (repoPassword) args.push(`--password=${repoPassword}`); - return exec.exec(helm, args); + await exec.exec(helm, args); + await exec.exec(helm, ["repo", "update"]) } return Promise.resolve() From 514898b419b7ed76a65e4478879c85a3abdc7c0c Mon Sep 17 00:00:00 2001 From: mpraski Date: Tue, 26 Jan 2021 10:23:37 +0100 Subject: [PATCH 21/33] Extract process config to main function --- index.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index 30cf8c14..7a4ab4dc 100644 --- a/index.js +++ b/index.js @@ -231,10 +231,6 @@ async function deploy(helm) { `--namespace=${namespace}`, ]; - process.env.XDG_DATA_HOME = "/root/.helm/" - process.env.XDG_CACHE_HOME = "/root/.helm/" - process.env.XDG_CONFIG_HOME = "/root/.helm/" - if (dryRun) args.push("--dry-run"); if (appName) args.push(`--set=app.name=${appName}`); if (version) args.push(`--set=app.version=${version}`); @@ -257,12 +253,6 @@ async function deploy(helm) { args.push("--atomic"); } - // Setup necessary files. - if (process.env.KUBECONFIG_FILE) { - process.env.KUBECONFIG = "./kubeconfig.yml"; - await writeFile(process.env.KUBECONFIG, process.env.KUBECONFIG_FILE); - } - await writeFile("./values.yml", values); core.debug(`env: KUBECONFIG="${process.env.KUBECONFIG}"`); @@ -300,6 +290,16 @@ async function run() { try { await status("pending"); + process.env.XDG_DATA_HOME = "/root/.helm/" + process.env.XDG_CACHE_HOME = "/root/.helm/" + process.env.XDG_CONFIG_HOME = "/root/.helm/" + + // Setup necessary files. + if (process.env.KUBECONFIG_FILE) { + process.env.KUBECONFIG = "./kubeconfig.yml"; + await writeFile(process.env.KUBECONFIG, process.env.KUBECONFIG_FILE); + } + const helm = getInput("helm") || "helm3"; core.debug(`param: helm = "${helm}"`); From 8176c4306cf1decf742bc356586a58e1bd2158be Mon Sep 17 00:00:00 2001 From: Ayrton Ricardo Date: Mon, 6 Dec 2021 17:17:41 +0100 Subject: [PATCH 22/33] Add missing input parameters to action.yml --- README.md | 2 +- action.yml | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 016aaa61..84fa1541 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ payload if the action was triggered by a deployment. - `namespace`: Kubernetes namespace name. (required) - `chart`: Helm chart path. If set to "app" this will use the built in helm chart found in this repository. (required) -- `chart_version`: The version of the helm chart you want to deploy (distinct from app version) +- `chart-version`: The version of the helm chart you want to deploy (distinct from app version) - `values`: Helm chart values, expected to be a YAML or JSON string. - `track`: Track for the deployment. If the track is not "stable" it activates the canary workflow described below. diff --git a/action.yml b/action.yml index cfec2692..5321e9df 100644 --- a/action.yml +++ b/action.yml @@ -46,6 +46,24 @@ inputs: version: description: Version of the app, usually commit sha works here. required: false + chart-version: + description: The version of the helm chart you want to deploy (distinct from app version) + required: false + track: + description: Track for the deployment. If the track is not "stable" it activates the canary workflow described in the docs. + required: false + repo: + description: Helm chart repository to be added. + required: false + repo-alias: + description: Helm repository alias that will be used. + required: false + repo-username: + description: Helm repository username if authentication is needed. + required: false + repo-password: + description: Helm repository password if authentication is needed. + required: false runs: using: docker image: Dockerfile From 84210d38131f63ec5edf67a307242a819d9db4b2 Mon Sep 17 00:00:00 2001 From: Jackson Coelho Date: Sun, 23 Jan 2022 14:35:38 +0100 Subject: [PATCH 23/33] Update docker image --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d9595117..e43be782 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.10.2 +FROM alpine:3 ENV BASE_URL="https://get.helm.sh" From 0619496ed59230f50e82295d63401a06cd14a17b Mon Sep 17 00:00:00 2001 From: Rafael Aybar Segura Date: Wed, 16 Mar 2022 14:05:17 +0100 Subject: [PATCH 24/33] Updated helm version --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index e43be782..1e9f8623 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM alpine:3 ENV BASE_URL="https://get.helm.sh" ENV HELM_2_FILE="helm-v2.17.0-linux-amd64.tar.gz" -ENV HELM_3_FILE="helm-v3.4.2-linux-amd64.tar.gz" +ENV HELM_3_FILE="helm-v3.8.1-linux-amd64.tar.gz" RUN apk add --no-cache ca-certificates \ --repository http://dl-3.alpinelinux.org/alpine/edge/community/ \ From 8ec80b5af4df70d0c36ed20ec8ac3b91fbda05c0 Mon Sep 17 00:00:00 2001 From: ArthurMa <4406arthur@gmail.com> Date: Tue, 26 Jul 2022 15:36:33 +0800 Subject: [PATCH 25/33] Update README.md correct helm version info --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 84fa1541..fb19eae4 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,8 @@ action will execute a `helm delete $service` #### Versions -- `helm`: v2.16.1 -- `helm3`: v3.0.0 +- `helm`: v2.17.0 +- `helm3`: v3.8.1 ### Environment From 1ad3b04c861d63cdc202e11ad1194df551eab491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Valverde?= Date: Mon, 28 Nov 2022 21:39:31 +0100 Subject: [PATCH 26/33] Update Dockerfile to use 3.10 in PYTHONPATH Latest Alpine release has upgraded the python version to 3.10 (See: https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.16.0#Python_upgraded_to_3.10) As the PYTHONPATH is harcoded, the Dockerfile needs to be updated accordingly --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 1e9f8623..c9554498 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,7 +21,7 @@ RUN apk add --no-cache ca-certificates \ # Init version 2 helm: helm init --client-only -ENV PYTHONPATH "/usr/lib/python3.8/site-packages/" +ENV PYTHONPATH "/usr/lib/python3.10/site-packages/" COPY . /usr/src/ ENTRYPOINT ["node", "/usr/src/index.js"] From d514ea0ce38fcfb7738d53e4482104625bba56de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Valverde?= Date: Fri, 2 Dec 2022 22:57:12 +0100 Subject: [PATCH 27/33] Pin Alpine version to 3.16 and update the python path again --- Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index c9554498..b7d4d867 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,13 @@ -FROM alpine:3 +FROM alpine:3.16.0 ENV BASE_URL="https://get.helm.sh" ENV HELM_2_FILE="helm-v2.17.0-linux-amd64.tar.gz" ENV HELM_3_FILE="helm-v3.8.1-linux-amd64.tar.gz" + +ENV PYTHONPATH "/usr/lib/python3.11/site-packages/" + RUN apk add --no-cache ca-certificates \ --repository http://dl-3.alpinelinux.org/alpine/edge/community/ \ jq curl bash nodejs aws-cli && \ @@ -21,7 +24,6 @@ RUN apk add --no-cache ca-certificates \ # Init version 2 helm: helm init --client-only -ENV PYTHONPATH "/usr/lib/python3.10/site-packages/" COPY . /usr/src/ ENTRYPOINT ["node", "/usr/src/index.js"] From ecb3030795703b1adeca15a60ab6afe5e1090956 Mon Sep 17 00:00:00 2001 From: Alex Tyshkevich Date: Sat, 17 Dec 2022 16:05:59 +0400 Subject: [PATCH 28/33] Add docker build workflow, change action to use prebuild image --- .github/workflows/build.yml | 36 ++++++++++++++++++++++++++++++++++++ action.yml | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..e02ddc53 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,36 @@ +name: Build docker image +on: + push: + branches: ["master"] + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - uses: docker/setup-buildx-action@v2 + + - uses: docker/login-action@v2 + with: + registry: "ghcr.io" + username: ${{ github.actor }} + password: ${{ github.GITHUB_TOKEN }} + + - uses: docker/metadata-action@v4 + id: meta + with: + images: "ghcr.io/condensedtea/helm" + tags: | + ${{ github.sha }} + latest + + - uses: docker/build-push-action@v3 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/action.yml b/action.yml index 5321e9df..8c2057c7 100644 --- a/action.yml +++ b/action.yml @@ -66,4 +66,4 @@ inputs: required: false runs: using: docker - image: Dockerfile + image: ghcr.io/condensedtea/helm From caf6b94dc61177d6d5cce7aa40918832ae641bd5 Mon Sep 17 00:00:00 2001 From: Alex Tyshkevich Date: Sat, 17 Dec 2022 16:08:45 +0400 Subject: [PATCH 29/33] fix ghcr password --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e02ddc53..9bdaf682 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ jobs: with: registry: "ghcr.io" username: ${{ github.actor }} - password: ${{ github.GITHUB_TOKEN }} + password: ${{ secrets.GITHUB_TOKEN }} - uses: docker/metadata-action@v4 id: meta From 9053a8ffe189ca61f6e034f491a51b6a94408b4b Mon Sep 17 00:00:00 2001 From: Alex Tyshkevich Date: Sat, 17 Dec 2022 16:10:21 +0400 Subject: [PATCH 30/33] add checkout step to build workflow --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9bdaf682..529f065a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,6 +26,8 @@ jobs: ${{ github.sha }} latest + - uses: actions/checkout@v3 + - uses: docker/build-push-action@v3 with: context: . From 8c03df1861a3aeb4b374b4b7deda850280f96cfd Mon Sep 17 00:00:00 2001 From: Alex Tyshkevich Date: Sat, 17 Dec 2022 16:30:37 +0400 Subject: [PATCH 31/33] change image path to parent repo --- .github/workflows/build.yml | 2 +- action.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 529f065a..88972e26 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,7 @@ jobs: - uses: docker/metadata-action@v4 id: meta with: - images: "ghcr.io/condensedtea/helm" + images: "ghcr.io/vimeda/helm" tags: | ${{ github.sha }} latest diff --git a/action.yml b/action.yml index 8c2057c7..46cafad7 100644 --- a/action.yml +++ b/action.yml @@ -66,4 +66,4 @@ inputs: required: false runs: using: docker - image: ghcr.io/condensedtea/helm + image: ghcr.io/vimeda/helm From 8edef423fefecf81b765552bcac53160d38e647e Mon Sep 17 00:00:00 2001 From: Alex Tyshkevich Date: Sat, 17 Dec 2022 16:57:55 +0400 Subject: [PATCH 32/33] fix image reference in action.yml --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 8c2057c7..3de78e60 100644 --- a/action.yml +++ b/action.yml @@ -66,4 +66,4 @@ inputs: required: false runs: using: docker - image: ghcr.io/condensedtea/helm + image: docker://ghcr.io/condensedtea/helm From 17cc8416b5c02dd8e54e7ced8d48c3389de56a96 Mon Sep 17 00:00:00 2001 From: libracoder Date: Wed, 19 Apr 2023 13:21:34 +0100 Subject: [PATCH 33/33] fix alpine package repository --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index b7d4d867..9b6f0ec0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ ENV HELM_3_FILE="helm-v3.8.1-linux-amd64.tar.gz" ENV PYTHONPATH "/usr/lib/python3.11/site-packages/" RUN apk add --no-cache ca-certificates \ - --repository http://dl-3.alpinelinux.org/alpine/edge/community/ \ + --repository https://dl-3.alpinelinux.org/alpine/latest-stable/community/ \ jq curl bash nodejs aws-cli && \ # Install helm version 2: curl -L ${BASE_URL}/${HELM_2_FILE} |tar xvz && \