Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
e10c1d5
helm 3.2.4
plmercereau Jul 26, 2020
141b50a
Update README.md
plmercereau Jul 26, 2020
8a27a27
feat: add optional KUBECONFIG_BASE64 env to pass base64-encoded value
shivanshs9 Sep 3, 2020
9be0bbe
Update README.md
LennardWesterveld Sep 29, 2020
b3a2d4c
Merge remote-tracking branch 'base64/base64-support'
LennardWesterveld Sep 29, 2020
2223246
Merge remote-tracking branch 'helm/master'
LennardWesterveld Sep 29, 2020
55bdaf0
feat: added helm repo add support to add repo's
LennardWesterveld Sep 29, 2020
969ea30
updated readme and action.yml
LennardWesterveld Sep 29, 2020
6b0a6a7
input renamed
LennardWesterveld Sep 29, 2020
dc11466
Updated actions and update index.js
LennardWesterveld Sep 29, 2020
eedda40
removed node_modules
LennardWesterveld Sep 29, 2020
17bc1ab
npm ci
LennardWesterveld Sep 29, 2020
4b16721
Added npm to packages
LennardWesterveld Sep 29, 2020
aeed6df
run after copy
LennardWesterveld Sep 29, 2020
25c9e06
Debug Dockerfile
LennardWesterveld Sep 29, 2020
16ea43a
npm ci fixure
LennardWesterveld Sep 29, 2020
0c8cdb5
Fixing test github action
LennardWesterveld Sep 29, 2020
58e4af8
update username password option
LennardWesterveld Sep 29, 2020
7503429
updated deps
LennardWesterveld Sep 29, 2020
b6b7956
update snap
LennardWesterveld Sep 29, 2020
e98a8de
fix error username/password
LennardWesterveld Sep 29, 2020
afe9a74
fix: updated helm v2 and v3
LennardWesterveld Dec 22, 2020
78d1a9a
fix: updated helm3 version
rmeijs Mar 3, 2021
b62f4da
Support passing a Kube token as an input
sbesselsen Aug 8, 2021
c91dbf5
Support configurable kube-context
sbesselsen Aug 8, 2021
214f9f6
Fix incorrect use of shellescape
sbesselsen Aug 8, 2021
6237b41
Add checks for helm3
sbesselsen Aug 8, 2021
5ff58f3
Try to fix issue with kube-token and kube-context
sbesselsen Aug 8, 2021
b4fc341
Output the token to debug
sbesselsen Aug 8, 2021
6accee5
Debug this crazy issue some more
sbesselsen Aug 8, 2021
aadd4d9
See if the token at least contains the right number of characters
sbesselsen Aug 8, 2021
8ac196e
Remove debug lines
sbesselsen Aug 8, 2021
2726b3b
Run helm list to debug
sbesselsen Aug 8, 2021
94ea7fc
Output the kubeconfig
sbesselsen Aug 8, 2021
f6ee66a
Try env vars instead of arguments
sbesselsen Aug 8, 2021
fad1164
Remove shellescape
sbesselsen Aug 9, 2021
2946a00
Merge pull request #1 from elseu/helm-token
LennardWesterveld Aug 9, 2021
514bc58
Support kube-token with helm2
sbesselsen Aug 9, 2021
7bac2e0
Do a little debug run with helm list
sbesselsen Aug 9, 2021
690ebab
Fix call signature in helm list test
sbesselsen Aug 9, 2021
26917f1
Helm list all namespaces to get useful debug output
sbesselsen Aug 9, 2021
e3baf74
Remove debug code
sbesselsen Aug 9, 2021
171b976
Improve docblock
sbesselsen Aug 9, 2021
baf0b2b
Improve documentation
sbesselsen Aug 9, 2021
ed88bf4
Merge pull request #2 from elseu/helm2-token
LennardWesterveld Aug 9, 2021
2b5943e
Fix automated tests
sbesselsen Aug 9, 2021
bb7a3a2
Merge branch 'helm2-token'
sbesselsen Aug 9, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
24 changes: 12 additions & 12 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
name: 'Test'
on: ['push']
on: [ 'push' ]

jobs:

test:
runs-on: 'ubuntu-latest'

steps:
- uses: 'actions/checkout@v1'
- uses: 'actions/checkout@v1'

- name: 'Build'
run: 'docker build -t helm .'
- name: 'Build'
run: 'docker build -t helm .'

- name: 'Test commands'
run: 'docker run --rm -i -v $PWD:/workspace --workdir=/workspace --entrypoint=/workspace/tests/test-snap.sh helm'
- name: 'Test commands'
run: 'docker run --rm -i -v $PWD/tests:/usr/src/tests --workdir=/usr/src --entrypoint=/usr/src/tests/test-snap.sh helm'

- name: 'Test chart'
run: 'docker run --rm -i -v $PWD:/workspace --workdir=/workspace --entrypoint=/workspace/tests/charts/test.sh helm'
- name: 'Test chart'
run: 'docker run --rm -i -v $PWD/tests:/usr/src/tests --workdir=/usr/src --entrypoint=/usr/src/tests/charts/test.sh helm'

- name: 'Test helm version'
run: 'docker run --rm -i --entrypoint=helm helm version -c'
- name: 'Test helm version'
run: 'docker run --rm -i --entrypoint=helm helm version -c'

- name: 'Test helm3 version'
run: 'docker run --rm -i --entrypoint=helm3 helm version'
- name: 'Test helm3 version'
run: 'docker run --rm -i --entrypoint=helm3 helm version'
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea
node_modules
10 changes: 7 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ 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_2_FILE="helm-v2.17.0-linux-amd64.tar.gz"
ENV HELM_3_FILE="helm-v3.5.2-linux-amd64.tar.gz"

RUN apk add --no-cache ca-certificates \
--repository http://dl-3.alpinelinux.org/alpine/edge/community/ \
jq curl bash nodejs aws-cli && \
jq curl bash nodejs npm aws-cli && \
# Install helm version 2:
curl -L ${BASE_URL}/${HELM_2_FILE} |tar xvz && \
mv linux-amd64/helm /usr/bin/helm && \
Expand All @@ -24,4 +24,8 @@ RUN apk add --no-cache ca-certificates \
ENV PYTHONPATH "/usr/lib/python3.8/site-packages/"

COPY . /usr/src/
WORKDIR /usr/src/

RUN npm ci

ENTRYPOINT ["node", "/usr/src/index.js"]
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Credits to https://github.com/deliverybot/helm just cloned this repo because, want to move forward with some new features and open pull request on original repo.
# Helm Action

Deploys a helm chart using GitHub actions. Supports canary deployments and
Expand Down Expand Up @@ -35,19 +36,25 @@ 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
- `repository`: specify the URL for a helm repo to come from
- `repository_password`: Password to login in to the repository.
- `repository_username`: Username to login to the repository.
- `repository_alias`: Alias of the repository.
- `kube-token`: Bearer token to use for authentication with Kubernetes. Can be fetched with e.g. elseu/sdu-eks-token-action.
- `kube-context`: Context to use to connect to the Kubernetes API.

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
action will execute a `helm delete $service`

#### Versions

- `helm`: v2.16.1
- `helm3`: v3.0.0
- `helm`: v2.16.12
- `helm3`: v3.3.4

### Environment

- `KUBECONFIG_FILE`: Kubeconfig file for Kubernetes cluster access.
- `KUBECONFIG_BASE64`: Kubeconfig as base64 for Kubernetes cluster access.

### Value file interpolation

Expand Down Expand Up @@ -81,7 +88,7 @@ jobs:
name: foobar
value-files: >-
[
"values.yaml",
"values.yaml",
"values.production.yaml"
]
env:
Expand Down
20 changes: 19 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Deliverybot Helm Action
name: Helm Deploy Action
description: Deploys a helm chart
author: deliverybot
icon: box
Expand Down Expand Up @@ -39,6 +39,24 @@ inputs:
version:
description: Version of the app, usually commit sha works here.
required: false
repository:
description: Respository URL
required: false
repository-password:
description: Repo Password
required: false
repository-username:
description: Repo Username
required: false
repository-alias:
description: Alias
required: false
kube-context:
description: Context to use to connect to the Kubernetes API.
required: false
kube-token:
description: Bearer token to use for authentication with Kubernetes. Can be fetched with e.g. elseu/sdu-eks-token-action
required: false
runs:
using: docker
image: Dockerfile
113 changes: 112 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ const core = require("@actions/core");
const github = require("@actions/github");
const exec = require("@actions/exec");
const fs = require("fs");
const os = require("os");
const path = require("path");
const util = require("util");
const yaml = require("js-yaml");
const Mustache = require("mustache");

const writeFile = util.promisify(fs.writeFile);
const readFile = util.promisify(fs.readFile);
const fileExists = util.promisify(fs.exists);
const required = { required: true };

/**
Expand Down Expand Up @@ -145,6 +149,61 @@ function deleteCmd(helm, namespace, release) {
return ["delete", "--purge", release];
}

/**
* Takes in a secret value and decodes it from base64.
*
* @param {string} secretVal
*/
function parseBase64(secretVal) {
return Buffer.from(secretVal, 'base64').toString('utf-8');
}

/**
* Create a rewritten kubeconfig file that includes a hardwired authentication token.
* @param {string} kubeconfigPath
* @param {string} kubeToken
*/
async function addTokenToKubeConfig(kubeconfigPath, kubeToken) {
if (!kubeconfigPath) {
kubeconfigPath = path.join(os.homedir(), ".kube", "config");
}
if (!await fileExists(kubeconfigPath)) {
throw new Error("Cannot find a kubeconfig file, which is required when using helm2 with the kube-token option");
}

// Read the kubeconfig file.
const kubeconfigData = await readFile(kubeconfigPath, { encoding: "utf8" });
const kubeconfigContent = yaml.load(kubeconfigData, {
filename: kubeconfigPath
});

// Create a user with the specified token.
const userName = "helm-deploy-action-token-user";
if (!kubeconfigContent.users) {
kubeconfigContent.users = [];
}
kubeconfigContent.users.push({
name: userName,
user: {
token: kubeToken
}
});

// Hook up that user to each context.
if (!kubeconfigContent.contexts) {
throw new Error("Cannot find contexts in the kubeconfig file, which are required when using helm2 with the kube-token option");
}
for (const context of kubeconfigContent.contexts) {
context.context.user = userName;
}

// Write it to a local temp file.
const newKubeconfigYaml = yaml.dump(kubeconfigContent);
const newKubeconfigPath = "./kubeconfig-with-token.yml";
await writeFile(newKubeconfigPath, newKubeconfigYaml);
return newKubeconfigPath;
}

/**
* Run executes the helm deployment.
*/
Expand All @@ -167,9 +226,15 @@ async function run() {
const helm = getInput("helm") || "helm";
const timeout = getInput("timeout");
const repository = getInput("repository");
const repository_password = getInput("repository-password");
const repository_username = getInput("repository-username");
const repository_alias = getInput("repository-alias");
const dryRun = core.getInput("dry-run");
const secrets = getSecrets(core.getInput("secrets"));
const kubeContext = getInput("kube-context");
const kubeToken = getInput("kube-token");

core.debug(`param: helm = "${helm}"`);
core.debug(`param: track = "${track}"`);
core.debug(`param: release = "${release}"`);
core.debug(`param: appName = "${appName}"`);
Expand All @@ -185,6 +250,11 @@ async function run() {
core.debug(`param: removeCanary = ${removeCanary}`);
core.debug(`param: timeout = "${timeout}"`);
core.debug(`param: repository = "${repository}"`);
core.debug(`param: repository_password = "${repository_password}"`);
core.debug(`param: repository_username = "${repository_username}"`);
core.debug(`param: repository_alias = "${repository_alias}"`);
core.debug(`param: kube-context = "${kubeContext}"`);
core.debug(`param: kube-token = "${kubeToken}"`);


// Setup command options and arguments.
Expand Down Expand Up @@ -212,7 +282,6 @@ async function run() {
if (version) args.push(`--set=app.version=${version}`);
if (chartVersion) args.push(`--version=${chartVersion}`);
if (timeout) args.push(`--timeout=${timeout}`);
if (repository) args.push(`--repo=${repository}`);
valueFiles.forEach(f => args.push(`--values=${f}`));
args.push("--values=./values.yml");

Expand All @@ -227,11 +296,50 @@ async function run() {
if (process.env.KUBECONFIG_FILE) {
process.env.KUBECONFIG = "./kubeconfig.yml";
await writeFile(process.env.KUBECONFIG, process.env.KUBECONFIG_FILE);
} else if (process.env.KUBECONFIG_BASE64) {
process.env.KUBECONFIG = "./kubeconfig.yml";
await writeFile(process.env.KUBECONFIG, parseBase64(process.env.KUBECONFIG_BASE64));
}
await writeFile("./values.yml", values);

if (kubeContext) args.push(`--kube-context=${kubeContext}`);

if (kubeToken) {
if (helm === "helm3") {
args.push(`--kube-token=${kubeToken}`);
} else {
// Helm 2 does not support the --kube-token option.
// So we rewrite the KUBECONFIG file to include the token in there.
process.env.KUBECONFIG = await addTokenToKubeConfig(process.env.KUBECONFIG, kubeToken);
}
}

core.debug(`env: KUBECONFIG="${process.env.KUBECONFIG}"`);

if (repository && repository_alias) {
core.info('Add repository');
const addRepoArgs = [
'repo',
'add',
]

if (repository_username && repository_password) {
addRepoArgs.push(`--username`, repository_username, `--password`, repository_password);
}

addRepoArgs.push(repository_alias, repository,)

await exec.exec(helm, addRepoArgs);

const updateRepoArgs = [
'repo',
'update'
]

core.info('Update repository');
await exec.exec(helm, updateRepoArgs);
}

// Render value files using github variables.
await renderFiles(valueFiles.concat(["./values.yml"]), {
secrets,
Expand All @@ -240,6 +348,7 @@ async function run() {

// Remove the canary deployment before continuing.
if (removeCanary) {
core.info('Remove canary helm chart');
core.debug(`removing canary ${appName}-canary`);
await exec.exec(helm, deleteCmd(helm, namespace, `${appName}-canary`), {
ignoreReturnCode: true
Expand All @@ -248,10 +357,12 @@ async function run() {

// Actually execute the deployment here.
if (task === "remove") {
core.info('Remove helm chart');
await exec.exec(helm, deleteCmd(helm, namespace, release), {
ignoreReturnCode: true
});
} else {
core.info('Install helm chart');
await exec.exec(helm, args);
}

Expand Down
1 change: 0 additions & 1 deletion node_modules/.bin/mustache

This file was deleted.

1 change: 0 additions & 1 deletion node_modules/.bin/semver

This file was deleted.

1 change: 0 additions & 1 deletion node_modules/.bin/which

This file was deleted.

7 changes: 0 additions & 7 deletions node_modules/@actions/core/LICENSE.md

This file was deleted.

Loading