Compare commits

..

2 Commits

Author SHA1 Message Date
github-actions[bot] 17f5181337 v3 new release (#192)
* Make pulling of images switchable (#178)

* Make namespace annotation switchable (#177)

* Bump tmpl from 1.0.4 to 1.0.5 (#152)

Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/daaku/nodejs-tmpl/releases)
- [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5)

---
updated-dependencies:
- dependency-name: tmpl
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump ansi-regex from 5.0.0 to 5.0.1 (#166)

Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/chalk/ansi-regex/releases)
- [Commits](https://github.com/chalk/ansi-regex/compare/v5.0.0...v5.0.1)

---
updated-dependencies:
- dependency-name: ansi-regex
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump minimist from 1.2.5 to 1.2.6 (#175)

Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Add directory functionality (#181)

* Modifying README to include instructions/examples for directory functionality (#183)

* Added some tests, not sure what else to try but gonna think of more examples

* forgot some files

* reverted package-lock.json

* Added empty dir test

* Cleaned up some extra spaces

* Add node modules and compiled JavaScript from main

* forgot to actually include functionality

* removed unnecessary files

* Update .gitignore

* Update .gitignore

* Update .gitignore

* thx david

* renamed searchFilesRec

* integrations test fix

* added examples to README

* added note about depth

* added additional note

* removed ticks

* changed version string

Co-authored-by: Jaiveer Katariya <jaiveerkatariya@Jaiveers-MacBook-Pro.local>
Co-authored-by: Oliver King <oking3@uncc.edu>

* Remove kubectl version example (#188)

* prefix for annotations (#191)

* Add node modules and compiled JavaScript from main

Co-authored-by: Jan Röhrich <roehrijn@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jaiveer Katariya <35347859+jaiveerk@users.noreply.github.com>
Co-authored-by: Jaiveer Katariya <jaiveerkatariya@Jaiveers-MacBook-Pro.local>
Co-authored-by: Oliver King <oking3@uncc.edu>
Co-authored-by: David Gamero <david340804@gmail.com>
2022-06-08 14:02:15 -04:00
github-actions[bot] e3c97bfc20 v3 new release (#182)
* Make pulling of images switchable (#178)

* Make namespace annotation switchable (#177)

* Bump tmpl from 1.0.4 to 1.0.5 (#152)

Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/daaku/nodejs-tmpl/releases)
- [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5)

---
updated-dependencies:
- dependency-name: tmpl
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump ansi-regex from 5.0.0 to 5.0.1 (#166)

Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/chalk/ansi-regex/releases)
- [Commits](https://github.com/chalk/ansi-regex/compare/v5.0.0...v5.0.1)

---
updated-dependencies:
- dependency-name: ansi-regex
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump minimist from 1.2.5 to 1.2.6 (#175)

Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Add directory functionality (#181)

* Add node modules and compiled JavaScript from main

Co-authored-by: Jan Röhrich <roehrijn@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jaiveer Katariya <35347859+jaiveerk@users.noreply.github.com>
Co-authored-by: Oliver King <oking3@uncc.edu>
2022-04-12 13:22:09 -04:00
34 changed files with 17395 additions and 17076 deletions
+6 -2
View File
@@ -21,11 +21,15 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Building latest changes
- name: Install dependencies
run: |
rm -rf node_modules/
npm install
npm run build
- name: Install ncc
run: npm i -g @vercel/ncc
- name: Build
run: ncc build src/run.ts -o lib
- name: Set name of ns
run: echo "::set-output name=name::$(echo `date +%Y%m%d%H%M%S`)"
+24 -14
View File
@@ -42,7 +42,7 @@ Following are the key capabilities of this action:
</tr>
<tr>
<td>manifests </br></br>(Required)</td>
<td>Path to the manifest files to be used for deployment</td>
<td>Path to the manifest files to be used for deployment. These can also be directories containing manifest files, in which case, all manifest files in the referenced directory at every depth will be deployed. Files not ending in .yml or .yaml will be ignored.</td>
</tr>
<tr>
<td>namespace </br></br>(Optional)
@@ -57,6 +57,10 @@ Following are the key capabilities of this action:
<tr>
<td>imagepullsecrets </br></br>(Optional)</td>
<td>Multiline input where each line contains the name of a docker-registry secret that has already been setup within the cluster. Each of these secret names are added under imagePullSecrets field for the workloads found in the input manifest files</td>
</tr>
<tr>
<td>pull-images</br></br>(Optional)</td>
<td>Acceptable values: true/false</br>Default value: true</br>Switch whether to pull the images from the registry before deployment to find out Dockerfile's path in order to add it to the annotations</td>
</tr>
<tr>
<td>strategy </br></br>(Optional)</td>
@@ -90,6 +94,10 @@ Following are the key capabilities of this action:
<td>force </br></br>(Optional)</td>
<td>Deploy when a previous deployment already exists. If true then '--force' argument is added to the apply command. Using '--force' argument is not recommended in production.</td>
</tr>
<tr>
<td>annotate-namespace</br></br>(Optional)</td>
<td>Acceptable values: true/false</br>Default value: true</br>Switch whether to annotate the namespace resources object or not</td>
</tr>
</table>
## Usage Examples
@@ -97,23 +105,21 @@ Following are the key capabilities of this action:
### Basic deployment (without any deployment strategy)
```yaml
- uses: Azure/k8s-deploy@v1.4
- uses: Azure/k8s-deploy@v3.1
with:
namespace: "myapp"
manifests: |
deployment.yaml
service.yaml
dir/manifestsDirectory
images: "contoso.azurecr.io/myapp:${{ event.run_id }}"
imagepullsecrets: |
image-pull-secret1
image-pull-secret2
kubectl-version: "latest"
```
### Canary deployment without service mesh
```yaml
- uses: Azure/k8s-deploy@v1.4
- uses: Azure/k8s-deploy@v3.1
with:
namespace: "myapp"
images: "contoso.azurecr.io/myapp:${{ event.run_id }}"
@@ -123,6 +129,7 @@ Following are the key capabilities of this action:
manifests: |
deployment.yaml
service.yaml
dir/manifestsDirectory
strategy: canary
action: deploy
percentage: 20
@@ -131,7 +138,7 @@ Following are the key capabilities of this action:
To promote/reject the canary created by the above snippet, the following YAML snippet could be used:
```yaml
- uses: Azure/k8s-deploy@v1.4
- uses: Azure/k8s-deploy@v3.1
with:
namespace: "myapp"
images: "contoso.azurecr.io/myapp:${{ event.run_id }}"
@@ -141,6 +148,7 @@ To promote/reject the canary created by the above snippet, the following YAML sn
manifests: |
deployment.yaml
service.yaml
dir/manifestsDirectory
strategy: canary
action: promote # substitute reject if you want to reject
```
@@ -148,7 +156,7 @@ To promote/reject the canary created by the above snippet, the following YAML sn
### Canary deployment based on Service Mesh Interface
```yaml
- uses: Azure/k8s-deploy@v1.4
- uses: Azure/k8s-deploy@v3.1
with:
namespace: "myapp"
images: "contoso.azurecr.io/myapp:${{ event.run_id }}"
@@ -158,6 +166,7 @@ To promote/reject the canary created by the above snippet, the following YAML sn
manifests: |
deployment.yaml
service.yaml
dir/manifestsDirectory
strategy: canary
action: deploy
traffic-split-method: smi
@@ -168,7 +177,7 @@ To promote/reject the canary created by the above snippet, the following YAML sn
To promote/reject the canary created by the above snippet, the following YAML snippet could be used:
```yaml
- uses: Azure/k8s-deploy@v1.4
- uses: Azure/k8s-deploy@v3.1
with:
namespace: "myapp"
images: "contoso.azurecr.io/myapp:${{ event.run_id }} "
@@ -178,6 +187,7 @@ To promote/reject the canary created by the above snippet, the following YAML sn
manifests: |
deployment.yaml
service.yaml
dir/manifestsDirectory
strategy: canary
traffic-split-method: smi
action: reject # substitute reject if you want to reject
@@ -186,7 +196,7 @@ To promote/reject the canary created by the above snippet, the following YAML sn
### Blue-Green deployment with different route methods
```yaml
- uses: Azure/k8s-deploy@v1.4
- uses: Azure/k8s-deploy@v3.1
with:
namespace: "myapp"
images: "contoso.azurecr.io/myapp:${{ event.run_id }}"
@@ -206,7 +216,7 @@ To promote/reject the canary created by the above snippet, the following YAML sn
To promote/reject the green workload created by the above snippet, the following YAML snippet could be used:
```yaml
- uses: Azure/k8s-deploy@v1.4
- uses: Azure/k8s-deploy@v3.1
with:
namespace: "myapp"
images: "contoso.azurecr.io/myapp:${{ event.run_id }}"
@@ -216,7 +226,7 @@ To promote/reject the green workload created by the above snippet, the following
manifests: |
deployment.yaml
service.yaml
ingress-yml
ingress.yml
strategy: blue-green
route-method: ingress # should be the same as the value when action was deploy
action: promote # substitute reject if you want to reject
@@ -263,7 +273,7 @@ jobs:
container-registry-password: ${{ secrets.REGISTRY_PASSWORD }}
secret-name: demo-k8s-secret
- uses: Azure/k8s-deploy@v1.4
- uses: Azure/k8s-deploy@v3.1
with:
action: deploy
manifests: |
@@ -309,7 +319,7 @@ jobs:
container-registry-password: ${{ secrets.REGISTRY_PASSWORD }}
secret-name: demo-k8s-secret
- uses: Azure/k8s-deploy@v1.4
- uses: Azure/k8s-deploy@v3.1
with:
action: deploy
manifests: |
+8
View File
@@ -15,6 +15,10 @@ inputs:
imagepullsecrets:
description: "Name of a docker-registry secret that has already been set up within the cluster. Each of these secret names are added under imagePullSecrets field for the workloads found in the input manifest files"
required: false
pull-images:
description: "Switch whether to pull the images from the registry before deployment to find out Dockerfile's path in order to add it to the annotations"
required: false
default: true
strategy:
description: "Deployment strategy to be used. Allowed values are none, canary and blue-green"
required: false
@@ -51,6 +55,10 @@ inputs:
description: "Github token"
default: ${{ github.token }}
required: true
annotate-namespace:
description: "Annotate the target namespace"
required: false
default: true
branding:
color: "green"
+71 -14
View File
@@ -18192,6 +18192,7 @@ const promote_1 = __nccwpck_require__(3604);
const reject_1 = __nccwpck_require__(7530);
const action_1 = __nccwpck_require__(2868);
const deploymentStrategy_1 = __nccwpck_require__(7023);
const fileUtils_1 = __nccwpck_require__(7446);
function run() {
return __awaiter(this, void 0, void 0, function* () {
// verify kubeconfig is set
@@ -18205,6 +18206,7 @@ function run() {
.split(/[\n,;]+/) // split into each individual manifest
.map((manifest) => manifest.trim()) // remove surrounding whitespace
.filter((manifest) => manifest.length > 0); // remove any blanks
const fullManifestFilePaths = fileUtils_1.getFilesFromDirectories(manifestFilePaths);
// create kubectl
const kubectlPath = yield kubectl_1.getKubectlPath();
const namespace = core.getInput("namespace") || "default";
@@ -18212,15 +18214,15 @@ function run() {
// run action
switch (action) {
case action_1.Action.DEPLOY: {
yield deploy_1.deploy(kubectl, manifestFilePaths, strategy);
yield deploy_1.deploy(kubectl, fullManifestFilePaths, strategy);
break;
}
case action_1.Action.PROMOTE: {
yield promote_1.promote(kubectl, manifestFilePaths, strategy);
yield promote_1.promote(kubectl, fullManifestFilePaths, strategy);
break;
}
case action_1.Action.REJECT: {
yield reject_1.reject(kubectl, manifestFilePaths, strategy);
yield reject_1.reject(kubectl, fullManifestFilePaths, strategy);
break;
}
default: {
@@ -19583,7 +19585,10 @@ function annotateResources(files, kubectl, resourceTypes, allPods, annotationKey
const namespace = core.getInput("namespace") || "default";
const lastSuccessSha = yield kubectlUtils_1.getLastSuccessfulRunSha(kubectl, namespace, annotationKey);
const annotationKeyValStr = `${annotationKey}=${workflowAnnotationUtils_1.getWorkflowAnnotations(lastSuccessSha, workflowFilePath, deploymentConfig)}`;
annotateResults.push(yield kubectl.annotate("namespace", namespace, annotationKeyValStr));
const annotateNamespace = !(core.getInput("annotate-namespace").toLowerCase() === "false");
if (annotateNamespace) {
annotateResults.push(yield kubectl.annotate("namespace", namespace, annotationKeyValStr));
}
annotateResults.push(yield kubectl.annotateFiles(files, annotationKeyValStr));
for (const resource of resourceTypes) {
if (resource.type.toLowerCase() !==
@@ -20082,13 +20087,16 @@ function getDeploymentConfig() {
}
const imageNames = core.getInput("images").split("\n") || [];
const imageDockerfilePathMap = {};
//Fetching from image label if available
for (const image of imageNames) {
try {
imageDockerfilePathMap[image] = yield getDockerfilePath(image);
}
catch (ex) {
core.warning(`Failed to get dockerfile path for image ${image.toString()}: ${ex} `);
const pullImages = !(core.getInput("pull-images").toLowerCase() === "false");
if (pullImages) {
//Fetching from image label if available
for (const image of imageNames) {
try {
imageDockerfilePathMap[image] = yield getDockerfilePath(image);
}
catch (ex) {
core.warning(`Failed to get dockerfile path for image ${image.toString()}: ${ex} `);
}
}
}
return Promise.resolve({
@@ -20135,7 +20143,7 @@ exports.checkDockerPath = checkDockerPath;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.writeManifestToFile = exports.writeObjectsToFile = exports.getTempDirectory = void 0;
exports.getFilesFromDirectories = exports.writeManifestToFile = exports.writeObjectsToFile = exports.getTempDirectory = void 0;
const fs = __nccwpck_require__(7147);
const path = __nccwpck_require__(1017);
const core = __nccwpck_require__(6024);
@@ -20186,6 +20194,46 @@ function getManifestFileName(kind, name) {
const tempDirectory = getTempDirectory();
return path.join(tempDirectory, path.basename(filePath));
}
function getFilesFromDirectories(filePaths) {
const fullPathSet = new Set();
filePaths.forEach((fileName => {
try {
if (fs.lstatSync(fileName).isDirectory()) {
recurisveManifestGetter(fileName).forEach((file) => { fullPathSet.add(file); });
}
else if (getFileExtension(fileName) === "yml" || getFileExtension(fileName) === "yaml") {
fullPathSet.add(fileName);
}
else {
core.debug(`Detected non-manifest file, ${fileName}, continuing... `);
}
}
catch (ex) {
throw Error(`Exception occurred while reading the file ${fileName}: ${ex}`);
}
}));
return Array.from(fullPathSet);
}
exports.getFilesFromDirectories = getFilesFromDirectories;
function recurisveManifestGetter(dirName) {
const toRet = [];
fs.readdirSync(dirName).forEach((fileName) => {
const fnwd = path.join(dirName, fileName);
if (fs.lstatSync(fnwd).isDirectory()) {
toRet.push(...recurisveManifestGetter(fnwd));
}
else if (getFileExtension(fileName) === "yml" || getFileExtension(fileName) === "yaml") {
toRet.push(path.join(dirName, fileName));
}
else {
core.debug(`Detected non-manifest file, ${fileName}, continuing... `);
}
});
return toRet;
}
function getFileExtension(fileName) {
return fileName.slice((fileName.lastIndexOf(".") - 1 >>> 0) + 2);
}
/***/ }),
@@ -20931,7 +20979,15 @@ exports.getTrafficSplitAPIVersion = getTrafficSplitAPIVersion;
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getWorkflowAnnotationKeyLabel = exports.getWorkflowAnnotations = void 0;
exports.getWorkflowAnnotationKeyLabel = exports.getWorkflowAnnotations = exports.prefixObjectKeys = void 0;
const ANNOTATION_PREFIX = "actions.github.com/";
function prefixObjectKeys(obj, prefix) {
return Object.keys(obj).reduce((newObj, key) => {
newObj[prefix + key] = obj[key];
return newObj;
}, {});
}
exports.prefixObjectKeys = prefixObjectKeys;
function getWorkflowAnnotations(lastSuccessRunSha, workflowFilePath, deploymentConfig) {
const annotationObject = {
run: process.env.GITHUB_RUN_ID,
@@ -20950,7 +21006,8 @@ function getWorkflowAnnotations(lastSuccessRunSha, workflowFilePath, deploymentC
helmChartPaths: deploymentConfig.helmChartFilePaths,
provider: "GitHub",
};
return JSON.stringify(annotationObject);
const prefixedAnnotationObject = prefixObjectKeys(annotationObject, ANNOTATION_PREFIX);
return JSON.stringify(prefixedAnnotationObject);
}
exports.getWorkflowAnnotations = getWorkflowAnnotations;
function getWorkflowAnnotationKeyLabel(workflowFilePath) {
+6075 -6075
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -2,7 +2,7 @@
module.exports = ({onlyFirst = false} = {}) => {
const pattern = [
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))'
].join('|');
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "ansi-regex",
"version": "5.0.0",
"version": "5.0.1",
"description": "Regular expression for matching ANSI escape codes",
"license": "MIT",
"repository": "chalk/ansi-regex",
+1 -1
View File
@@ -1,4 +1,4 @@
# ansi-regex [![Build Status](https://travis-ci.org/chalk/ansi-regex.svg?branch=master)](https://travis-ci.org/chalk/ansi-regex)
# ansi-regex
> Regular expression for matching [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code)
+6 -2
View File
@@ -70,7 +70,7 @@ module.exports = function (args, opts) {
var o = obj;
for (var i = 0; i < keys.length-1; i++) {
var key = keys[i];
if (key === '__proto__') return;
if (isConstructorOrProto(o, key)) return;
if (o[key] === undefined) o[key] = {};
if (o[key] === Object.prototype || o[key] === Number.prototype
|| o[key] === String.prototype) o[key] = {};
@@ -79,7 +79,7 @@ module.exports = function (args, opts) {
}
var key = keys[keys.length - 1];
if (key === '__proto__') return;
if (isConstructorOrProto(o, key)) return;
if (o === Object.prototype || o === Number.prototype
|| o === String.prototype) o = {};
if (o === Array.prototype) o = [];
@@ -243,3 +243,7 @@ function isNumber (x) {
return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
}
function isConstructorOrProto (obj, key) {
return key === 'constructor' && typeof obj[key] === 'function' || key === '__proto__';
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "minimist",
"version": "1.2.5",
"version": "1.2.6",
"description": "parse argument options",
"main": "index.js",
"devDependencies": {
+4 -1
View File
@@ -34,7 +34,10 @@ $ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz
Previous versions had a prototype pollution bug that could cause privilege
escalation in some circumstances when handling untrusted user input.
Please use version 1.2.3 or later: https://snyk.io/vuln/SNYK-JS-MINIMIST-559764
Please use version 1.2.6 or later:
* https://security.snyk.io/vuln/SNYK-JS-MINIMIST-2429795 (version <=1.2.5)
* https://snyk.io/vuln/SNYK-JS-MINIMIST-559764 (version <=1.2.3)
# methods
+16
View File
@@ -42,3 +42,19 @@ test('proto pollution (constructor)', function (t) {
t.equal(argv.y, undefined);
t.end();
});
test('proto pollution (constructor function)', function (t) {
var argv = parse(['--_.concat.constructor.prototype.y', '123']);
function fnToBeTested() {}
t.equal(fnToBeTested.y, undefined);
t.equal(argv.y, undefined);
t.end();
});
// powered by snyk - https://github.com/backstage/backstage/issues/10343
test('proto pollution (constructor function) snyk', function (t) {
var argv = parse('--_.constructor.constructor.prototype.foo bar'.split(' '));
t.equal((function(){}).foo, undefined);
t.equal(argv.y, undefined);
t.end();
})
-3
View File
@@ -1,3 +0,0 @@
language: node_js
node_js:
- 0.6
+1 -1
View File
@@ -1,4 +1,4 @@
var INTERPOLATE = /{([\s\S]+?)}/g
var INTERPOLATE = /{([^{]+?)}/g
module.exports = function(str, data) {
var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
+6 -4
View File
@@ -1,17 +1,19 @@
{
"name": "tmpl",
"description": "JavaScript micro templates.",
"version": "1.0.4",
"version": "1.0.5",
"license": "BSD-3-Clause",
"homepage": "https://github.com/nshah/nodejs-tmpl",
"homepage": "https://github.com/daaku/nodejs-tmpl",
"author": "Naitik Shah <n@daaku.org>",
"main": "lib/tmpl",
"repository": {
"type": "git",
"url": "https://github.com/daaku/nodejs-tmpl"
},
"scripts": { "test": "NODE_PATH=./lib mocha --ui exports" },
"scripts": {
"test": "NODE_PATH=./lib mocha --ui exports"
},
"devDependencies": {
"mocha": "0.12.x"
"mocha": "^9.1.1"
}
}
+10940 -10940
View File
File diff suppressed because it is too large Load Diff
+6 -4
View File
@@ -5,6 +5,7 @@ import { promote } from "./actions/promote";
import { reject } from "./actions/reject";
import { Action, parseAction } from "./types/action";
import { parseDeploymentStrategy } from "./types/deploymentStrategy";
import { getFilesFromDirectories } from "./utilities/fileUtils";
export async function run() {
// verify kubeconfig is set
@@ -23,7 +24,8 @@ export async function run() {
.split(/[\n,;]+/) // split into each individual manifest
.map((manifest) => manifest.trim()) // remove surrounding whitespace
.filter((manifest) => manifest.length > 0); // remove any blanks
const fullManifestFilePaths = getFilesFromDirectories(manifestFilePaths)
// create kubectl
const kubectlPath = await getKubectlPath();
const namespace = core.getInput("namespace") || "default";
@@ -32,15 +34,15 @@ export async function run() {
// run action
switch (action) {
case Action.DEPLOY: {
await deploy(kubectl, manifestFilePaths, strategy);
await deploy(kubectl, fullManifestFilePaths, strategy);
break;
}
case Action.PROMOTE: {
await promote(kubectl, manifestFilePaths, strategy);
await promote(kubectl, fullManifestFilePaths, strategy);
break;
}
case Action.REJECT: {
await reject(kubectl, manifestFilePaths, strategy);
await reject(kubectl, fullManifestFilePaths, strategy);
break;
}
default: {
+7 -3
View File
@@ -173,9 +173,13 @@ async function annotateResources(
workflowFilePath,
deploymentConfig
)}`;
annotateResults.push(
await kubectl.annotate("namespace", namespace, annotationKeyValStr)
);
const annotateNamespace = !(core.getInput("annotate-namespace").toLowerCase() === "false");
if (annotateNamespace) {
annotateResults.push(
await kubectl.annotate("namespace", namespace, annotationKeyValStr)
);
}
annotateResults.push(await kubectl.annotateFiles(files, annotationKeyValStr));
for (const resource of resourceTypes) {
+11 -8
View File
@@ -26,14 +26,17 @@ export async function getDeploymentConfig(): Promise<DeploymentConfig> {
const imageNames = core.getInput("images").split("\n") || [];
const imageDockerfilePathMap: { [id: string]: string } = {};
//Fetching from image label if available
for (const image of imageNames) {
try {
imageDockerfilePathMap[image] = await getDockerfilePath(image);
} catch (ex) {
core.warning(
`Failed to get dockerfile path for image ${image.toString()}: ${ex} `
);
const pullImages = !(core.getInput("pull-images").toLowerCase() === "false");
if (pullImages) {
//Fetching from image label if available
for (const image of imageNames) {
try {
imageDockerfilePathMap[image] = await getDockerfilePath(image);
} catch (ex) {
core.warning(
`Failed to get dockerfile path for image ${image.toString()}: ${ex} `
);
}
}
}
+49
View File
@@ -0,0 +1,49 @@
import {
getFilesFromDirectories
} from "./fileUtils";
import * as path from "path";
describe("File utils", () => {
it("detects files in nested directories and ignores non-manifest files and empty dirs", () => {
const testPath = path.join("test", "unit", "manifests")
const testSearch: string[] = getFilesFromDirectories([testPath])
const expectedManifests =
[
"test/unit/manifests/manifest_test_dir/another_layer/deep-ingress.yaml",
"test/unit/manifests/manifest_test_dir/another_layer/deep-service.yaml",
"test/unit/manifests/manifest_test_dir/nested-test-service.yaml",
"test/unit/manifests/test-ingress.yml",
"test/unit/manifests/test-service.yml"
]
// is there a more efficient way to test equality w random order?
expect(testSearch).toHaveLength(5);
expectedManifests.forEach((fileName) => {
expect(testSearch).toContain(fileName)
})
});
it("crashes when an invalid file is provided", () => {
const badPath = path.join("test", "unit", "manifests", "nonexistent.yaml")
const goodPath = path.join("test", "unit", "manifests", "manifest_test_dir")
expect(() => {getFilesFromDirectories([badPath, goodPath])}).toThrowError()
});
it("doesn't duplicate files when nested dir included", () => {
const outerPath = path.join("test", "unit", "manifests")
const fileAtOuter = path.join("test", "unit", "manifests", "test-service.yml")
const innerPath = path.join("test", "unit", "manifests", "manifest_test_dir")
expect(getFilesFromDirectories([outerPath, fileAtOuter, innerPath])).toHaveLength(5)
})
});
// files that don't exist / nested files that don't exist / something else with non-manifest
// lots of combinations of pointing to a directory and non yaml/yaml file
// similarly named files in different folders
+46
View File
@@ -61,3 +61,49 @@ function getManifestFileName(kind: string, name: string) {
const tempDirectory = getTempDirectory();
return path.join(tempDirectory, path.basename(filePath));
}
export function getFilesFromDirectories(
filePaths: string[]
): string[]{
const fullPathSet: Set<string> = new Set<string>()
filePaths.forEach((fileName => {
try {
if(fs.lstatSync(fileName).isDirectory()){
recurisveManifestGetter(fileName).forEach((file) => {fullPathSet.add(file)})
} else if(getFileExtension(fileName) === "yml" || getFileExtension(fileName) === "yaml"){
fullPathSet.add(fileName)
} else{
core.debug(`Detected non-manifest file, ${fileName}, continuing... ` )
}
} catch (ex) {
throw Error(
`Exception occurred while reading the file ${fileName}: ${ex}`
);
}
}))
return Array.from(fullPathSet)
}
function recurisveManifestGetter(dirName: string): string[]{
const toRet: string[] = []
fs.readdirSync(dirName).forEach((fileName) => {
const fnwd: string = path.join(dirName, fileName)
if(fs.lstatSync(fnwd).isDirectory()){
toRet.push(...recurisveManifestGetter(fnwd))
} else if(getFileExtension(fileName) === "yml" || getFileExtension(fileName) === "yaml"){
toRet.push(path.join(dirName, fileName))
} else{
core.debug(`Detected non-manifest file, ${fileName}, continuing... ` )
}
})
return toRet
}
function getFileExtension(fileName: string){
return fileName.slice((fileName.lastIndexOf(".") - 1 >>> 0) + 2)
}
@@ -0,0 +1,18 @@
import { prefixObjectKeys } from "../utilities/workflowAnnotationUtils";
describe("WorkflowAnnotationUtils", () => {
describe("prefixObjectKeys", () => {
it("should prefix an object with a given prefix", () => {
const obj = {
foo: "bar",
baz: "qux",
};
const prefix = "prefix.";
const expected = {
"prefix.foo": "bar",
"prefix.baz": "qux",
};
expect(prefixObjectKeys(obj, prefix)).toEqual(expected);
});
});
});
+11 -1
View File
@@ -1,5 +1,14 @@
import { DeploymentConfig } from "../types/deploymentConfig";
const ANNOTATION_PREFIX = "actions.github.com/";
export function prefixObjectKeys(obj: any, prefix: string): any {
return Object.keys(obj).reduce((newObj, key) => {
newObj[prefix + key] = obj[key];
return newObj;
}, {});
}
export function getWorkflowAnnotations(
lastSuccessRunSha: string,
workflowFilePath: string,
@@ -22,7 +31,8 @@ export function getWorkflowAnnotations(
helmChartPaths: deploymentConfig.helmChartFilePaths,
provider: "GitHub",
};
return JSON.stringify(annotationObject);
const prefixedAnnotationObject = prefixObjectKeys(annotationObject, ANNOTATION_PREFIX);
return JSON.stringify(prefixedAnnotationObject);
}
export function getWorkflowAnnotationKeyLabel(
@@ -0,0 +1 @@
weaker than the average human?
+52
View File
@@ -0,0 +1,52 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /testpath
backend:
serviceName: nginx-service
servicePort: 80
- path: /testpath2
backend:
serviceName: unrouted-service
servicePort: 80
+33
View File
@@ -0,0 +1,33 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80