Skip to content

Commit

Permalink
Squashing commits for first pass at implementing action
Browse files Browse the repository at this point in the history
  • Loading branch information
dave-mcconnell committed Mar 3, 2020
1 parent 5d267bc commit 5840b5b
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 130 deletions.
13 changes: 6 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
on: [push]

jobs:
hello_world_job:
Test_Job:
runs-on: ubuntu-latest
name: A job to say hello
name: Test job
steps:
# To use this repository's private action, you must check out the repository
# - name: Checkout
# uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v2
- name: Test this action
uses: ./ # Uses an action in the root directory
uses: ./
with:
access-token: ${{ secrets.CR_TOKEN }}
source-charts-folder: 'test-charts'
destination-repo: ${{ secrets.CR_TOKEN }}
destination-repo: dave-mcconnell/helm-charts
destination-charts-folder: 'charts'
67 changes: 29 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# Helm Publish
# Helm Publish For Microservices

GitHub Action to package and deploy your Helm charts to GitHub Pages

Based upon [gatsby-gh-pages-action](https://github.com/enriikke/gatsby-gh-pages-action)
Based upon [helm-gh-pages-action](https://github.com/funkypenguin/helm-gh-pages-action)

## Usage

This GitHub Action will run `helm package` for every chart folder in the `charts` directory of your repository and
deploy it to GitHub Pages for you! Here's a basic workflow example:
This GitHub Action allows you to co-locate your Helm Chart alongside your application code. When pushing/submitting a pull request, the Helm Chart can be produced as an artifact to a Helm Chart repository hosted using GitHub Pages.

The Action will run `helm package` for every chart folder in the `charts` directory of your repository and
deploy it to GitHub Pages. A basic example workflow is below:

```yml
name: Helm Publish
Expand All @@ -22,12 +24,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: J12934/helm-gh-pages-action@master
- uses: dave-mcconnell/helm-gh-pages-microservices@master
with:
access-token: ${{ secrets.ACCESS_TOKEN }}
access-token: ${{ secrets.CR_TOKEN }}
source-charts-folder: 'test-charts' // location of helm charts in your code repo
destination-repo: yourusername/helm-charts-repo
```
### Knobs & Handles
### Configuration Options
This Action is fairly simple but it does provide you with a couple of
configuration options:
Expand All @@ -37,43 +41,30 @@ configuration options:
Helm finished building it. You should store this as a [secret][github-repo-secret]
in your repository. Provided as an [input][github-action-input].

- **deploy-branch**: The branch expected by GitHub to have the static files
needed for your site. For org and user pages it should always be `master`.
This is where the packaged charts and index.yaml will be pushed to. Provided as an
[input][github-action-input].
Defaults to `master`.
- **source-charts-folder**: The folder to package helm charts from.
Defaults to `charts`.

- **destination-repo**: The destination repository you want to push your Helm chart to.
This is a required field.

- **destination-branch**: The destination branch you want to push your Helm chart to.
Defaults to `master`.

- **charts-folder**: Charts folder of your repository. Defaults to `charts`
- **destination-charts-folder**: The destination folder you want to copy the packages Helm chart to.
Defaults to `charts`.

- **destination-charts-folder**: The version of Helm you're using - either v2 or v3.
Defaults to `v3`.

### Org or User Pages

Create a repository with the format `<YOUR/ORG USERNAME>.github.io`, push your
helm sources to a branch other than `master` and add this GitHub Action to
your workflow! 🚀😃

### CNAME

You have a custom domain you would like to use? Fancy! 😎 This Action's got you
covered! Assuming you have already set up your DNS provider as defined in the
[GitHub Pages docs][github-pages-domain-docs], all we need next is a `CNAME`
file at the root of your project with the domain you would like to use. For
example:

```CNAME
imenrique.com
```

> Notice that it's **all capitals CNAME** 😊.

### Assumptions

TODO

## That's It

Have fun building! ✨
## Related Links

[github-access-token]: https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line
[github-action-input]: https://help.github.com/en/articles/workflow-syntax-for-github-actions#jobsjob_idstepswith
[github-pages-domain-docs]: https://help.github.com/en/articles/using-a-custom-domain-with-github-pages
[github-repo-secret]: https://help.github.com/en/articles/virtual-environments-for-github-actions#creating-and-using-secrets-encrypted-variables
- [github-access-token]: https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line
- [github-action-input]: https://help.github.com/en/articles/workflow-syntax-for-github-actions#jobsjob_idstepswith
- [github-pages-domain-docs]: https://help.github.com/en/articles/using-a-custom-domain-with-github-pages
- [github-repo-secret]: https://help.github.com/en/articles/virtual-environments-for-github-actions#creating-and-using-secrets-encrypted-variables
12 changes: 10 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,25 @@ inputs:
access-token:
description: 'A personal access token needed to push your site after it has been built.'
required: true
source-charts-folder:
description: 'The folder to package helm charts from'
required: false
default: 'charts'
destination-repo:
description: 'The destination repository you want to push your Helm chart to.'
required: true
destination-branch:
description: 'The destination branch you want to push your Helm chart to.'
required: false
default: 'master'
charts-folder:
description: 'The folder in which the helm charts are located'
destination-charts-folder:
description: 'The folder to copy packaged helm charts into'
required: false
default: 'charts'
helm-version:
description: 'The version of Helm being used - either v2 or v3'
required: false
default: 'v3'
runs:
using: 'node12'
main: 'index.js'
196 changes: 113 additions & 83 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,31 @@ const ioUtil = require('@actions/io/lib/io-util');
const { readdirSync } = require('fs');
const path = require('path');

const getDirectories = fileName =>
readdirSync(fileName, {
withFileTypes: true,
})
.filter(dirent => dirent.isDirectory())
.filter(dirent => !(/(^|\/)\.[^\/\.]/g).test(dirent))
.map(dirent => dirent.name);

async function run() {

try {
const sourceBranch = github.context.ref
const accessToken = core.getInput('access-token');
const sourceChartsDir = core.getInput('source-charts-folder') | 'charts';

const sourceRepo = `${github.context.repo.owner}/${github.context.repo.repo}`;
const sourceBranch = github.context.ref.replace('refs/heads/', '')
const sourceChartsDir = core.getInput('source-charts-folder') ? core.getInput('source-charts-folder') : 'charts';

const destinationRepo = core.getInput('destination-repo');
const destinationBranch = core.getInput('destination-branch') | 'master'
const destinationChartsDir = core.getInput('destination-charts-folder') | 'charts';
const destinationBranch = core.getInput('destination-branch') ? core.getInput('destination-branch') : 'master'
const destinationChartsDir = core.getInput('destination-charts-folder') ?core.getInput('destination-charts-folder') : 'charts';

let useHelm3 = true;
if (!core.getInput('helm-version')) {
useHelm3 = true
}
else useHelm3 = core.getInput('helm-version') === 'v3' ? true : false;

console.log('Running Push Helm Chart job with:')
console.log('Source Branch:' + sourceBranch)
console.log('Source Charts Directory:' + sourceChartsDir)
console.log('Destination Repo:' + destinationRepo)
console.log('Destination Branch:' + destinationBranch)
console.log('Destination Charts Directory:' + destinationChartsDir)

if (!accessToken) {
core.setFailed(
Expand All @@ -38,87 +47,108 @@ async function run() {
return;
}

const sourceRepo = `${github.context.repo.owner}/${github.context.repo.repo}`;
const sourceRepoURL = `https://${accessToken}@github.com/${sourceRepo}.git`;
const destinationRepoURL = `https://${accessToken}@github.com/${destinationRepo}.git`;

// clone source repo
console.log(`Deploying to repo: ${sourceRepo} and branch: ${sourceBranch}`);
await exec.exec(`git clone`, ['-b', sourceBranch, sourceRepoURL, 'output'], {
cwd: './sourceRepo',
});

// git config
await exec.exec(`git config user.name`, [github.context.actor], {
cwd: './output',
});
await exec.exec(
`git config user.email`,
[`${github.context.actor}@users.noreply.github.com`],
{ cwd: './output' }
);

// package helm charts
const chartDirectories = getDirectories(path.resolve(`./sourceRepo/${sourceChartsDir}`));

console.log('Charts dir content');
await exec.exec(`ls`, ['-I ".*"'], { cwd: `./sourceRepo/${sourceChartsDir}` });
for (const chartDirname of chartDirectories) {
console.log(`Resolving helm chart dependency in directory ${chartDirname}`);
await exec.exec(
`helm dependency update`,
[],
{ cwd: `./sourceRepo/${sourceChartsDir}/${chartDirname}` }
);

console.log(`Packaging helm chart in directory ${chartDirname}`);
await exec.exec(
`helm package`,
[chartDirname, '--destination', '../output'],
{ cwd: `./sourceRepo/${sourceChartsDir}` }
);
if (useHelm3) {
await InstallHelm3Latest();
}

console.log('Packaged all helm charts.');
await ConfigureGit()
await CloneGitRepo(sourceRepo, sourceBranch, accessToken, 'sourceRepo')
await CloneGitRepo(destinationRepo, destinationBranch, accessToken, 'destinationRepo')

const cnameExists = await ioUtil.exists('./CNAME');
if (cnameExists) {
console.log('Copying CNAME over.');
await io.cp('./CNAME', './output/CNAME', { force: true });
console.log('Finished copying CNAME.');
}
await PackageHelmCharts(`./sourceRepo/${sourceChartsDir}`, `../../destinationRepo/${destinationChartsDir}`)
await GenerateIndex()
await AddCommitPushToGitRepo(`./destinationRepo`, `${github.context.sha}`, destinationBranch)

} catch (error) {
core.setFailed(error.message);
}
}

const getDirectories = fileName =>
readdirSync(fileName, {
withFileTypes: true,
})
.filter(dirent => dirent.isDirectory())
.filter(dirent => !(/(^|\/)\.[^\/\.]/g).test(dirent))
.map(dirent => dirent.name);

const InstallHelm3Latest = async () => {
await exec.exec(`curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3`, [], { cwd: `./` });
await exec.exec(`chmod 700 get_helm.sh`, [], { cwd: `./` });
await exec.exec(`./get_helm.sh`, [], { cwd: `./` });

await exec.exec(`helm version`, [], { cwd: `./` }
)
}

const ConfigureGit = async () => {

await exec.exec(`git config --global user.name`, [github.context.actor], {
cwd: './',
});

await exec.exec(
`git config --global user.email`,
[`${github.context.actor}@users.noreply.github.com`],
{ cwd: './' }
);
}

const CloneGitRepo = async (repoName, branchName, accessToken, cloneDirectory) => {

const repoURL = `https://${accessToken}@github.com/${repoName}.git`;
await exec.exec(`git clone`, ['-b', branchName, repoURL, cloneDirectory], {
cwd: './',
});

}

// clone destination repo
await exec.exec(`git clone`, ['-b', destinationBranch, destinationRepoURL, 'destinationRepo'], {
cwd: './',
});
const PackageHelmCharts = async (chartsDir, destinationChartsDir) => {

// move published chart
await exec.exec(`mv`, ['./sourceRepo/*.tgz', `./DestinationRepo/${destinationChartsDir}`], {
cwd: './',
});
const chartDirectories = getDirectories(path.resolve(chartsDir));

// push to
await exec.exec(`git add`, ['.'], { cwd: './DestinationRepo' });
console.log('Charts dir content');
await exec.exec(`ls`, ['-I ".*"'], { cwd: chartsDir });
for (const chartDirname of chartDirectories) {

console.log(`Resolving helm chart dependency in directory ${chartDirname}`);
await exec.exec(
`git commit`,
['-m', `Deployed via Helm Publish Action for ${github.context.sha}`],
{ cwd: './output' }
`helm dependency update`,
[],
{ cwd: `${chartsDir}/${chartDirname}` }
);

console.log(`Packaging helm chart in directory ${chartDirname}`);
await exec.exec(
`helm package`,
[chartDirname, '--destination', destinationChartsDir],
{ cwd: chartsDir }
);
await exec.exec(`git push`, ['-u', 'origin', `${destinationBranch}`], {
cwd: './output',
});
console.log('Finished deploying your site.');
}
console.log('Packaged all helm charts.');
}

console.log('Enjoy! ✨');
// generate index
console.log(`Building index.yaml`);
await exec.exec(`helm repo index`, `./output`);
const GenerateIndex = async () => {

console.log(`Successfully build index.yaml.`);
} catch (error) {
core.setFailed(error.message);
}
// generate index
console.log(`Building index.yaml`);
await exec.exec(`helm repo index`, `./destinationRepo`);
console.log(`Successfully generated index.yaml.`);
}

const AddCommitPushToGitRepo = async (workingDir, gitSha, branch) => {
await exec.exec(`git status`, [], { cwd: workingDir });
await exec.exec(`git add`, ['.'], { cwd: workingDir });
await exec.exec(`git status`, [], { cwd: workingDir });
await exec.exec(
`git commit`,
['-m', `Deployed via Helm Publish Action for ${gitSha}`],
{ cwd: workingDir }
);
await exec.exec(`git push`, ['-u', 'origin', `${branch}`],
{ cwd: workingDir }
);
console.log(`Pushed to ${workingDir}`);
}

run();

0 comments on commit 5840b5b

Please sign in to comment.