mirror of
https://github.com/Azure/k8s-deploy.git
synced 2026-06-22 19:59:26 +08:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5782616d03 | |||
| c7b34876bb | |||
| d89c89ba4e |
@@ -128,7 +128,7 @@ Following are the key capabilities of this action:
|
|||||||
### Basic deployment (without any deployment strategy)
|
### Basic deployment (without any deployment strategy)
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: Azure/k8s-deploy@v3.1
|
- uses: Azure/k8s-deploy@v4
|
||||||
with:
|
with:
|
||||||
namespace: 'myapp'
|
namespace: 'myapp'
|
||||||
manifests: |
|
manifests: |
|
||||||
@@ -162,7 +162,7 @@ Following are the key capabilities of this action:
|
|||||||
### Canary deployment without service mesh
|
### Canary deployment without service mesh
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: Azure/k8s-deploy@v3.1
|
- uses: Azure/k8s-deploy@v4
|
||||||
with:
|
with:
|
||||||
namespace: 'myapp'
|
namespace: 'myapp'
|
||||||
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
|
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
|
||||||
@@ -181,7 +181,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:
|
To promote/reject the canary created by the above snippet, the following YAML snippet could be used:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: Azure/k8s-deploy@v3.1
|
- uses: Azure/k8s-deploy@v4
|
||||||
with:
|
with:
|
||||||
namespace: 'myapp'
|
namespace: 'myapp'
|
||||||
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
|
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
|
||||||
@@ -199,7 +199,7 @@ To promote/reject the canary created by the above snippet, the following YAML sn
|
|||||||
### Canary deployment based on Service Mesh Interface
|
### Canary deployment based on Service Mesh Interface
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: Azure/k8s-deploy@v3.1
|
- uses: Azure/k8s-deploy@v4
|
||||||
with:
|
with:
|
||||||
namespace: 'myapp'
|
namespace: 'myapp'
|
||||||
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
|
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
|
||||||
@@ -220,7 +220,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:
|
To promote/reject the canary created by the above snippet, the following YAML snippet could be used:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: Azure/k8s-deploy@v3.1
|
- uses: Azure/k8s-deploy@v4
|
||||||
with:
|
with:
|
||||||
namespace: 'myapp'
|
namespace: 'myapp'
|
||||||
images: 'contoso.azurecr.io/myapp:${{ event.run_id }} '
|
images: 'contoso.azurecr.io/myapp:${{ event.run_id }} '
|
||||||
@@ -239,7 +239,7 @@ To promote/reject the canary created by the above snippet, the following YAML sn
|
|||||||
### Blue-Green deployment with different route methods
|
### Blue-Green deployment with different route methods
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: Azure/k8s-deploy@v3.1
|
- uses: Azure/k8s-deploy@v4
|
||||||
with:
|
with:
|
||||||
namespace: 'myapp'
|
namespace: 'myapp'
|
||||||
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
|
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
|
||||||
@@ -259,7 +259,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:
|
To promote/reject the green workload created by the above snippet, the following YAML snippet could be used:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: Azure/k8s-deploy@v3.1
|
- uses: Azure/k8s-deploy@v4
|
||||||
with:
|
with:
|
||||||
namespace: 'myapp'
|
namespace: 'myapp'
|
||||||
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
|
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
|
||||||
@@ -316,7 +316,7 @@ jobs:
|
|||||||
container-registry-password: ${{ secrets.REGISTRY_PASSWORD }}
|
container-registry-password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||||
secret-name: demo-k8s-secret
|
secret-name: demo-k8s-secret
|
||||||
|
|
||||||
- uses: Azure/k8s-deploy@v3.1
|
- uses: Azure/k8s-deploy@v4
|
||||||
with:
|
with:
|
||||||
action: deploy
|
action: deploy
|
||||||
manifests: |
|
manifests: |
|
||||||
@@ -362,7 +362,7 @@ jobs:
|
|||||||
container-registry-password: ${{ secrets.REGISTRY_PASSWORD }}
|
container-registry-password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||||
secret-name: demo-k8s-secret
|
secret-name: demo-k8s-secret
|
||||||
|
|
||||||
- uses: Azure/k8s-deploy@v3.1
|
- uses: Azure/k8s-deploy@v4
|
||||||
with:
|
with:
|
||||||
action: deploy
|
action: deploy
|
||||||
manifests: |
|
manifests: |
|
||||||
|
|||||||
+65
-31
@@ -140,7 +140,6 @@ const file_command_1 = __nccwpck_require__(8466);
|
|||||||
const utils_1 = __nccwpck_require__(7369);
|
const utils_1 = __nccwpck_require__(7369);
|
||||||
const os = __importStar(__nccwpck_require__(2037));
|
const os = __importStar(__nccwpck_require__(2037));
|
||||||
const path = __importStar(__nccwpck_require__(1017));
|
const path = __importStar(__nccwpck_require__(1017));
|
||||||
const uuid_1 = __nccwpck_require__(487);
|
|
||||||
const oidc_utils_1 = __nccwpck_require__(7557);
|
const oidc_utils_1 = __nccwpck_require__(7557);
|
||||||
/**
|
/**
|
||||||
* The code to exit an action
|
* The code to exit an action
|
||||||
@@ -170,20 +169,9 @@ function exportVariable(name, val) {
|
|||||||
process.env[name] = convertedVal;
|
process.env[name] = convertedVal;
|
||||||
const filePath = process.env['GITHUB_ENV'] || '';
|
const filePath = process.env['GITHUB_ENV'] || '';
|
||||||
if (filePath) {
|
if (filePath) {
|
||||||
const delimiter = `ghadelimiter_${uuid_1.v4()}`;
|
return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val));
|
||||||
// These should realistically never happen, but just in case someone finds a way to exploit uuid generation let's not allow keys or values that contain the delimiter.
|
|
||||||
if (name.includes(delimiter)) {
|
|
||||||
throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`);
|
|
||||||
}
|
|
||||||
if (convertedVal.includes(delimiter)) {
|
|
||||||
throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`);
|
|
||||||
}
|
|
||||||
const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;
|
|
||||||
file_command_1.issueCommand('ENV', commandValue);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
command_1.issueCommand('set-env', { name }, convertedVal);
|
|
||||||
}
|
}
|
||||||
|
command_1.issueCommand('set-env', { name }, convertedVal);
|
||||||
}
|
}
|
||||||
exports.exportVariable = exportVariable;
|
exports.exportVariable = exportVariable;
|
||||||
/**
|
/**
|
||||||
@@ -201,7 +189,7 @@ exports.setSecret = setSecret;
|
|||||||
function addPath(inputPath) {
|
function addPath(inputPath) {
|
||||||
const filePath = process.env['GITHUB_PATH'] || '';
|
const filePath = process.env['GITHUB_PATH'] || '';
|
||||||
if (filePath) {
|
if (filePath) {
|
||||||
file_command_1.issueCommand('PATH', inputPath);
|
file_command_1.issueFileCommand('PATH', inputPath);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
command_1.issueCommand('add-path', {}, inputPath);
|
command_1.issueCommand('add-path', {}, inputPath);
|
||||||
@@ -241,7 +229,10 @@ function getMultilineInput(name, options) {
|
|||||||
const inputs = getInput(name, options)
|
const inputs = getInput(name, options)
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.filter(x => x !== '');
|
.filter(x => x !== '');
|
||||||
return inputs;
|
if (options && options.trimWhitespace === false) {
|
||||||
|
return inputs;
|
||||||
|
}
|
||||||
|
return inputs.map(input => input.trim());
|
||||||
}
|
}
|
||||||
exports.getMultilineInput = getMultilineInput;
|
exports.getMultilineInput = getMultilineInput;
|
||||||
/**
|
/**
|
||||||
@@ -274,8 +265,12 @@ exports.getBooleanInput = getBooleanInput;
|
|||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
function setOutput(name, value) {
|
function setOutput(name, value) {
|
||||||
|
const filePath = process.env['GITHUB_OUTPUT'] || '';
|
||||||
|
if (filePath) {
|
||||||
|
return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value));
|
||||||
|
}
|
||||||
process.stdout.write(os.EOL);
|
process.stdout.write(os.EOL);
|
||||||
command_1.issueCommand('set-output', { name }, value);
|
command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value));
|
||||||
}
|
}
|
||||||
exports.setOutput = setOutput;
|
exports.setOutput = setOutput;
|
||||||
/**
|
/**
|
||||||
@@ -404,7 +399,11 @@ exports.group = group;
|
|||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
function saveState(name, value) {
|
function saveState(name, value) {
|
||||||
command_1.issueCommand('save-state', { name }, value);
|
const filePath = process.env['GITHUB_STATE'] || '';
|
||||||
|
if (filePath) {
|
||||||
|
return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value));
|
||||||
|
}
|
||||||
|
command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value));
|
||||||
}
|
}
|
||||||
exports.saveState = saveState;
|
exports.saveState = saveState;
|
||||||
/**
|
/**
|
||||||
@@ -470,13 +469,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.issueCommand = void 0;
|
exports.prepareKeyValueMessage = exports.issueFileCommand = void 0;
|
||||||
// We use any as a valid input type
|
// We use any as a valid input type
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
const fs = __importStar(__nccwpck_require__(7147));
|
const fs = __importStar(__nccwpck_require__(7147));
|
||||||
const os = __importStar(__nccwpck_require__(2037));
|
const os = __importStar(__nccwpck_require__(2037));
|
||||||
|
const uuid_1 = __nccwpck_require__(487);
|
||||||
const utils_1 = __nccwpck_require__(7369);
|
const utils_1 = __nccwpck_require__(7369);
|
||||||
function issueCommand(command, message) {
|
function issueFileCommand(command, message) {
|
||||||
const filePath = process.env[`GITHUB_${command}`];
|
const filePath = process.env[`GITHUB_${command}`];
|
||||||
if (!filePath) {
|
if (!filePath) {
|
||||||
throw new Error(`Unable to find environment variable for file command ${command}`);
|
throw new Error(`Unable to find environment variable for file command ${command}`);
|
||||||
@@ -488,7 +488,22 @@ function issueCommand(command, message) {
|
|||||||
encoding: 'utf8'
|
encoding: 'utf8'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.issueCommand = issueCommand;
|
exports.issueFileCommand = issueFileCommand;
|
||||||
|
function prepareKeyValueMessage(key, value) {
|
||||||
|
const delimiter = `ghadelimiter_${uuid_1.v4()}`;
|
||||||
|
const convertedValue = utils_1.toCommandValue(value);
|
||||||
|
// These should realistically never happen, but just in case someone finds a
|
||||||
|
// way to exploit uuid generation let's not allow keys or values that contain
|
||||||
|
// the delimiter.
|
||||||
|
if (key.includes(delimiter)) {
|
||||||
|
throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`);
|
||||||
|
}
|
||||||
|
if (convertedValue.includes(delimiter)) {
|
||||||
|
throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`);
|
||||||
|
}
|
||||||
|
return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`;
|
||||||
|
}
|
||||||
|
exports.prepareKeyValueMessage = prepareKeyValueMessage;
|
||||||
//# sourceMappingURL=file-command.js.map
|
//# sourceMappingURL=file-command.js.map
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -22002,12 +22017,20 @@ function checkManifestStability(kubectl, resources) {
|
|||||||
exports.checkManifestStability = checkManifestStability;
|
exports.checkManifestStability = checkManifestStability;
|
||||||
function annotateAndLabelResources(files, kubectl, resourceTypes, allPods) {
|
function annotateAndLabelResources(files, kubectl, resourceTypes, allPods) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const defaultWorkflowFileName = 'k8s-deploy-failed-workflow-annotation';
|
||||||
const githubToken = core.getInput('token');
|
const githubToken = core.getInput('token');
|
||||||
const workflowFilePath = yield githubUtils_1.getWorkflowFilePath(githubToken);
|
let workflowFilePath;
|
||||||
|
try {
|
||||||
|
workflowFilePath = yield githubUtils_1.getWorkflowFilePath(githubToken);
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
core.warning(`Failed to extract workflow file name: ${ex}`);
|
||||||
|
workflowFilePath = defaultWorkflowFileName;
|
||||||
|
}
|
||||||
const deploymentConfig = yield dockerUtils_1.getDeploymentConfig();
|
const deploymentConfig = yield dockerUtils_1.getDeploymentConfig();
|
||||||
const annotationKeyLabel = workflowAnnotationUtils_1.getWorkflowAnnotationKeyLabel();
|
const annotationKeyLabel = workflowAnnotationUtils_1.getWorkflowAnnotationKeyLabel();
|
||||||
yield annotateResources(files, kubectl, resourceTypes, allPods, annotationKeyLabel, workflowFilePath, deploymentConfig);
|
yield annotateResources(files, kubectl, resourceTypes, allPods, annotationKeyLabel, workflowFilePath, deploymentConfig).catch((err) => core.warning(`Failed to annotate resources: ${err} `));
|
||||||
yield labelResources(files, kubectl, annotationKeyLabel);
|
yield labelResources(files, kubectl, annotationKeyLabel).catch((err) => core.warning(`Failed to label resources: ${err}`));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.annotateAndLabelResources = annotateAndLabelResources;
|
exports.annotateAndLabelResources = annotateAndLabelResources;
|
||||||
@@ -22060,7 +22083,7 @@ function labelResources(files, kubectl, label) {
|
|||||||
const labelResults = [];
|
const labelResults = [];
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
try {
|
try {
|
||||||
const labelResult = yield kubectl.labelFiles(files, labels);
|
const labelResult = yield kubectl.labelFiles(file, labels);
|
||||||
labelResults.push(labelResult);
|
labelResults.push(labelResult);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
@@ -22345,13 +22368,17 @@ class Kubectl {
|
|||||||
let newReplicaSet = '';
|
let newReplicaSet = '';
|
||||||
if (result === null || result === void 0 ? void 0 : result.stdout) {
|
if (result === null || result === void 0 ? void 0 : result.stdout) {
|
||||||
const stdout = result.stdout.split('\n');
|
const stdout = result.stdout.split('\n');
|
||||||
|
core.debug('stdout from getNewReplicaSet is ' + JSON.stringify(stdout));
|
||||||
stdout.forEach((line) => {
|
stdout.forEach((line) => {
|
||||||
const newreplicaset = 'newreplicaset';
|
const newreplicaset = 'newreplicaset';
|
||||||
if (line && line.toLowerCase().indexOf(newreplicaset) > -1)
|
if (line && line.toLowerCase().indexOf(newreplicaset) > -1) {
|
||||||
|
core.debug(`found string of interest for replicaset, line is ${line}`);
|
||||||
|
core.debug(`substring is ${line.substring(newreplicaset.length).trim()}`);
|
||||||
newReplicaSet = line
|
newReplicaSet = line
|
||||||
.substring(newreplicaset.length)
|
.substring(newreplicaset.length)
|
||||||
.trim()
|
.trim()
|
||||||
.split(' ')[0];
|
.split(' ')[0];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return newReplicaSet;
|
return newReplicaSet;
|
||||||
@@ -23788,8 +23815,9 @@ exports.getTrafficSplitAPIVersion = getTrafficSplitAPIVersion;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.cleanLabel = exports.getWorkflowAnnotationKeyLabel = exports.getWorkflowAnnotations = void 0;
|
exports.removeInvalidLabelCharacters = exports.cleanLabel = exports.getWorkflowAnnotationKeyLabel = exports.getWorkflowAnnotations = exports.VALID_LABEL_REGEX = void 0;
|
||||||
const ANNOTATION_PREFIX = 'actions.github.com';
|
const ANNOTATION_PREFIX = 'actions.github.com';
|
||||||
|
exports.VALID_LABEL_REGEX = /([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]/;
|
||||||
function getWorkflowAnnotations(lastSuccessRunSha, workflowFilePath, deploymentConfig) {
|
function getWorkflowAnnotations(lastSuccessRunSha, workflowFilePath, deploymentConfig) {
|
||||||
const annotationObject = {
|
const annotationObject = {
|
||||||
run: process.env.GITHUB_RUN_ID,
|
run: process.env.GITHUB_RUN_ID,
|
||||||
@@ -23821,14 +23849,20 @@ exports.getWorkflowAnnotationKeyLabel = getWorkflowAnnotationKeyLabel;
|
|||||||
* @returns cleaned label
|
* @returns cleaned label
|
||||||
*/
|
*/
|
||||||
function cleanLabel(label) {
|
function cleanLabel(label) {
|
||||||
let removedInvalidChars = label
|
let removedInvalidChars = removeInvalidLabelCharacters(label);
|
||||||
|
const regexResult = exports.VALID_LABEL_REGEX.exec(removedInvalidChars) || [
|
||||||
|
'github-workflow-file'
|
||||||
|
];
|
||||||
|
return regexResult[0];
|
||||||
|
}
|
||||||
|
exports.cleanLabel = cleanLabel;
|
||||||
|
function removeInvalidLabelCharacters(label) {
|
||||||
|
return label
|
||||||
.replace(/\s/gi, '_')
|
.replace(/\s/gi, '_')
|
||||||
.replace(/[\/\\\|]/gi, '-')
|
.replace(/[\/\\\|]/gi, '-')
|
||||||
.replace(/[^-A-Za-z0-9_.]/gi, '');
|
.replace(/[^-A-Za-z0-9_.]/gi, '');
|
||||||
const regex = /([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]/;
|
|
||||||
return regex.exec(removedInvalidChars)[0] || '';
|
|
||||||
}
|
}
|
||||||
exports.cleanLabel = cleanLabel;
|
exports.removeInvalidLabelCharacters = removeInvalidLabelCharacters;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|||||||
Generated
+7
-7
@@ -9,7 +9,7 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.9.1",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/exec": "^1.0.0",
|
"@actions/exec": "^1.0.0",
|
||||||
"@actions/io": "^1.0.0",
|
"@actions/io": "^1.0.0",
|
||||||
"@actions/tool-cache": "1.1.2",
|
"@actions/tool-cache": "1.1.2",
|
||||||
@@ -30,9 +30,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/core": {
|
"node_modules/@actions/core": {
|
||||||
"version": "1.9.1",
|
"version": "1.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
||||||
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
|
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/http-client": "^2.0.1",
|
"@actions/http-client": "^2.0.1",
|
||||||
"uuid": "^8.3.2"
|
"uuid": "^8.3.2"
|
||||||
@@ -6529,9 +6529,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": {
|
"@actions/core": {
|
||||||
"version": "1.9.1",
|
"version": "1.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
||||||
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
|
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@actions/http-client": "^2.0.1",
|
"@actions/http-client": "^2.0.1",
|
||||||
"uuid": "^8.3.2"
|
"uuid": "^8.3.2"
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@
|
|||||||
"format-check": "prettier --check ."
|
"format-check": "prettier --check ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.9.1",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/exec": "^1.0.0",
|
"@actions/exec": "^1.0.0",
|
||||||
"@actions/io": "^1.0.0",
|
"@actions/io": "^1.0.0",
|
||||||
"@actions/tool-cache": "1.1.2",
|
"@actions/tool-cache": "1.1.2",
|
||||||
|
|||||||
@@ -150,8 +150,15 @@ export async function annotateAndLabelResources(
|
|||||||
resourceTypes: Resource[],
|
resourceTypes: Resource[],
|
||||||
allPods: any
|
allPods: any
|
||||||
) {
|
) {
|
||||||
|
const defaultWorkflowFileName = 'k8s-deploy-failed-workflow-annotation'
|
||||||
const githubToken = core.getInput('token')
|
const githubToken = core.getInput('token')
|
||||||
const workflowFilePath = await getWorkflowFilePath(githubToken)
|
let workflowFilePath
|
||||||
|
try {
|
||||||
|
workflowFilePath = await getWorkflowFilePath(githubToken)
|
||||||
|
} catch (ex) {
|
||||||
|
core.warning(`Failed to extract workflow file name: ${ex}`)
|
||||||
|
workflowFilePath = defaultWorkflowFileName
|
||||||
|
}
|
||||||
|
|
||||||
const deploymentConfig = await getDeploymentConfig()
|
const deploymentConfig = await getDeploymentConfig()
|
||||||
const annotationKeyLabel = getWorkflowAnnotationKeyLabel()
|
const annotationKeyLabel = getWorkflowAnnotationKeyLabel()
|
||||||
@@ -164,8 +171,11 @@ export async function annotateAndLabelResources(
|
|||||||
annotationKeyLabel,
|
annotationKeyLabel,
|
||||||
workflowFilePath,
|
workflowFilePath,
|
||||||
deploymentConfig
|
deploymentConfig
|
||||||
|
).catch((err) => core.warning(`Failed to annotate resources: ${err} `))
|
||||||
|
|
||||||
|
await labelResources(files, kubectl, annotationKeyLabel).catch((err) =>
|
||||||
|
core.warning(`Failed to label resources: ${err}`)
|
||||||
)
|
)
|
||||||
await labelResources(files, kubectl, annotationKeyLabel)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function annotateResources(
|
async function annotateResources(
|
||||||
@@ -258,7 +268,7 @@ async function labelResources(
|
|||||||
const labelResults = []
|
const labelResults = []
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
try {
|
try {
|
||||||
const labelResult = await kubectl.labelFiles(files, labels)
|
const labelResult = await kubectl.labelFiles(file, labels)
|
||||||
labelResults.push(labelResult)
|
labelResults.push(labelResult)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
core.warning(`failed to annotate resource: ${e}`)
|
core.warning(`failed to annotate resource: ${e}`)
|
||||||
|
|||||||
@@ -70,13 +70,21 @@ export class Kubectl {
|
|||||||
let newReplicaSet = ''
|
let newReplicaSet = ''
|
||||||
if (result?.stdout) {
|
if (result?.stdout) {
|
||||||
const stdout = result.stdout.split('\n')
|
const stdout = result.stdout.split('\n')
|
||||||
|
core.debug('stdout from getNewReplicaSet is ' + JSON.stringify(stdout))
|
||||||
stdout.forEach((line: string) => {
|
stdout.forEach((line: string) => {
|
||||||
const newreplicaset = 'newreplicaset'
|
const newreplicaset = 'newreplicaset'
|
||||||
if (line && line.toLowerCase().indexOf(newreplicaset) > -1)
|
if (line && line.toLowerCase().indexOf(newreplicaset) > -1) {
|
||||||
|
core.debug(
|
||||||
|
`found string of interest for replicaset, line is ${line}`
|
||||||
|
)
|
||||||
|
core.debug(
|
||||||
|
`substring is ${line.substring(newreplicaset.length).trim()}`
|
||||||
|
)
|
||||||
newReplicaSet = line
|
newReplicaSet = line
|
||||||
.substring(newreplicaset.length)
|
.substring(newreplicaset.length)
|
||||||
.trim()
|
.trim()
|
||||||
.split(' ')[0]
|
.split(' ')[0]
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import {cleanLabel} from '../utilities/workflowAnnotationUtils'
|
import {
|
||||||
|
cleanLabel,
|
||||||
|
removeInvalidLabelCharacters,
|
||||||
|
VALID_LABEL_REGEX
|
||||||
|
} from '../utilities/workflowAnnotationUtils'
|
||||||
|
|
||||||
describe('WorkflowAnnotationUtils', () => {
|
describe('WorkflowAnnotationUtils', () => {
|
||||||
describe('cleanLabel', () => {
|
describe('cleanLabel', () => {
|
||||||
@@ -16,5 +20,14 @@ describe('WorkflowAnnotationUtils', () => {
|
|||||||
cleanLabel('Workflow Name / With Slashes / And Spaces')
|
cleanLabel('Workflow Name / With Slashes / And Spaces')
|
||||||
).toEqual('Workflow_Name_-_With_Slashes_-_And_Spaces')
|
).toEqual('Workflow_Name_-_With_Slashes_-_And_Spaces')
|
||||||
})
|
})
|
||||||
|
it('should return a blank string when regex fails (https://github.com/Azure/k8s-deploy/issues/266)', () => {
|
||||||
|
const label = '持续部署'
|
||||||
|
expect(cleanLabel(label)).toEqual('github-workflow-file')
|
||||||
|
|
||||||
|
let removedInvalidChars = removeInvalidLabelCharacters(label)
|
||||||
|
|
||||||
|
const regexResult = VALID_LABEL_REGEX.exec(removedInvalidChars)
|
||||||
|
expect(regexResult).toBe(null)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import {DeploymentConfig} from '../types/deploymentConfig'
|
|||||||
|
|
||||||
const ANNOTATION_PREFIX = 'actions.github.com'
|
const ANNOTATION_PREFIX = 'actions.github.com'
|
||||||
|
|
||||||
|
export const VALID_LABEL_REGEX = /([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]/
|
||||||
|
|
||||||
export function getWorkflowAnnotations(
|
export function getWorkflowAnnotations(
|
||||||
lastSuccessRunSha: string,
|
lastSuccessRunSha: string,
|
||||||
workflowFilePath: string,
|
workflowFilePath: string,
|
||||||
@@ -37,11 +39,17 @@ export function getWorkflowAnnotationKeyLabel(): string {
|
|||||||
* @returns cleaned label
|
* @returns cleaned label
|
||||||
*/
|
*/
|
||||||
export function cleanLabel(label: string): string {
|
export function cleanLabel(label: string): string {
|
||||||
let removedInvalidChars = label
|
let removedInvalidChars = removeInvalidLabelCharacters(label)
|
||||||
|
|
||||||
|
const regexResult = VALID_LABEL_REGEX.exec(removedInvalidChars) || [
|
||||||
|
'github-workflow-file'
|
||||||
|
]
|
||||||
|
return regexResult[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeInvalidLabelCharacters(label: string): string {
|
||||||
|
return label
|
||||||
.replace(/\s/gi, '_')
|
.replace(/\s/gi, '_')
|
||||||
.replace(/[\/\\\|]/gi, '-')
|
.replace(/[\/\\\|]/gi, '-')
|
||||||
.replace(/[^-A-Za-z0-9_.]/gi, '')
|
.replace(/[^-A-Za-z0-9_.]/gi, '')
|
||||||
|
|
||||||
const regex = /([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]/
|
|
||||||
return regex.exec(removedInvalidChars)[0] || ''
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user