mirror of
https://github.com/Azure/k8s-deploy.git
synced 2026-06-24 21:50:00 +08:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ebc294c887 | |||
| 72a09f4051 | |||
| a17f35ba63 | |||
| 7b11ddb1d5 | |||
| ecec5912ba |
@@ -43,6 +43,14 @@ Following are the key capabilities of this action:
|
|||||||
<tr>
|
<tr>
|
||||||
<td>manifests </br></br>(Required)</td>
|
<td>manifests </br></br>(Required)</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>
|
<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>strategy </br></br>(Required)</td>
|
||||||
|
<td>Acceptable values: basic/canary/blue-green. <br>
|
||||||
|
Default value: basic
|
||||||
|
<br>Deployment strategy to be used while applying manifest files on the cluster.
|
||||||
|
<br>basic - Template is force applied to all pods when deploying to cluster. NOTE: Can only be used with action == deploy
|
||||||
|
<br>canary - Canary deployment strategy is used when deploying to the cluster.<br>blue-green - Blue-Green deployment strategy is used when deploying to cluster.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>namespace </br></br>(Optional)
|
<td>namespace </br></br>(Optional)
|
||||||
@@ -62,11 +70,6 @@ Following are the key capabilities of this action:
|
|||||||
<td>pull-images</br></br>(Optional)</td>
|
<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>
|
<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>
|
||||||
<tr>
|
|
||||||
<td>strategy </br></br>(Optional)</td>
|
|
||||||
<td>Acceptable values: none/canary/blue-green. <br>
|
|
||||||
Deployment strategy to be used while applying manifest files on the cluster.<br>none - No deployment strategy is used when deploying.<br>canary - Canary deployment strategy is used when deploying to the cluster.<br>blue-green - Blue-Green deployment strategy is used when deploying to cluster.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>traffic-split-method </br></br>(Optional)</td>
|
<td>traffic-split-method </br></br>(Optional)</td>
|
||||||
<td>Acceptable values: pod/smi.<br> Default value: pod <br>SMI: Percentage traffic split is done at request level using service mesh. Service mesh has to be setup by cluster admin. Orchestration of <a href="https://github.com/servicemeshinterface/smi-spec/blob/master/apis/traffic-split/v1alpha3/traffic-split.md" data-raw-source="TrafficSplit](https://github.com/deislabs/smi-spec/blob/master/traffic-split.md)">TrafficSplit</a> objects of SMI is handled by this action. <br>Pod: Percentage split not possible at request level in the absence of service mesh. Percentage input is used to calculate the replicas for baseline and canary as a percentage of replicas specified in the input manifests for the stable variant.</td>
|
<td>Acceptable values: pod/smi.<br> Default value: pod <br>SMI: Percentage traffic split is done at request level using service mesh. Service mesh has to be setup by cluster admin. Orchestration of <a href="https://github.com/servicemeshinterface/smi-spec/blob/master/apis/traffic-split/v1alpha3/traffic-split.md" data-raw-source="TrafficSplit](https://github.com/deislabs/smi-spec/blob/master/traffic-split.md)">TrafficSplit</a> objects of SMI is handled by this action. <br>Pod: Percentage split not possible at request level in the absence of service mesh. Percentage input is used to calculate the replicas for baseline and canary as a percentage of replicas specified in the input manifests for the stable variant.</td>
|
||||||
|
|||||||
+3
-3
@@ -20,9 +20,9 @@ inputs:
|
|||||||
required: false
|
required: false
|
||||||
default: true
|
default: true
|
||||||
strategy:
|
strategy:
|
||||||
description: 'Deployment strategy to be used. Allowed values are none, canary and blue-green'
|
description: 'Deployment strategy to be used. Allowed values are basic, canary and blue-green'
|
||||||
required: false
|
required: true
|
||||||
default: 'none'
|
default: 'basic'
|
||||||
route-method:
|
route-method:
|
||||||
description: 'Route based on service, ingress or SMI for blue-green strategy'
|
description: 'Route based on service, ingress or SMI for blue-green strategy'
|
||||||
required: false
|
required: false
|
||||||
|
|||||||
Generated
+16
@@ -22,6 +22,7 @@
|
|||||||
"@types/jest": "^26.0.0",
|
"@types/jest": "^26.0.0",
|
||||||
"@types/js-yaml": "^3.12.7",
|
"@types/js-yaml": "^3.12.7",
|
||||||
"@types/node": "^12.20.41",
|
"@types/node": "^12.20.41",
|
||||||
|
"@vercel/ncc": "^0.34.0",
|
||||||
"jest": "^26.0.0",
|
"jest": "^26.0.0",
|
||||||
"prettier": "2.7.1",
|
"prettier": "2.7.1",
|
||||||
"ts-jest": "^26.0.0",
|
"ts-jest": "^26.0.0",
|
||||||
@@ -1155,6 +1156,15 @@
|
|||||||
"integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==",
|
"integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@vercel/ncc": {
|
||||||
|
"version": "0.34.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.34.0.tgz",
|
||||||
|
"integrity": "sha512-G9h5ZLBJ/V57Ou9vz5hI8pda/YQX5HQszCs3AmIus3XzsmRn/0Ptic5otD3xVST8QLKk7AMk7AqpsyQGN7MZ9A==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"ncc": "dist/ncc/cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/abab": {
|
"node_modules/abab": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
|
||||||
@@ -7086,6 +7096,12 @@
|
|||||||
"integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==",
|
"integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@vercel/ncc": {
|
||||||
|
"version": "0.34.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.34.0.tgz",
|
||||||
|
"integrity": "sha512-G9h5ZLBJ/V57Ou9vz5hI8pda/YQX5HQszCs3AmIus3XzsmRn/0Ptic5otD3xVST8QLKk7AMk7AqpsyQGN7MZ9A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"abab": {
|
"abab": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
|
||||||
|
|||||||
+2
-1
@@ -4,7 +4,7 @@
|
|||||||
"author": "Deepak Sattiraju",
|
"author": "Deepak Sattiraju",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc --outDir ./lib --rootDir ./src",
|
"build": "ncc build src/run.ts -o lib",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"format": "prettier --write .",
|
"format": "prettier --write .",
|
||||||
"format-check": "prettier --check ."
|
"format-check": "prettier --check ."
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
"@types/jest": "^26.0.0",
|
"@types/jest": "^26.0.0",
|
||||||
"@types/js-yaml": "^3.12.7",
|
"@types/js-yaml": "^3.12.7",
|
||||||
"@types/node": "^12.20.41",
|
"@types/node": "^12.20.41",
|
||||||
|
"@vercel/ncc": "^0.34.0",
|
||||||
"jest": "^26.0.0",
|
"jest": "^26.0.0",
|
||||||
"prettier": "2.7.1",
|
"prettier": "2.7.1",
|
||||||
"ts-jest": "^26.0.0",
|
"ts-jest": "^26.0.0",
|
||||||
|
|||||||
+10
-5
@@ -26,7 +26,7 @@ export async function deploy(
|
|||||||
core.debug('Input manifest files: ' + inputManifestFiles)
|
core.debug('Input manifest files: ' + inputManifestFiles)
|
||||||
|
|
||||||
// deploy manifests
|
// deploy manifests
|
||||||
core.info('Deploying manifests')
|
core.startGroup('Deploying manifests')
|
||||||
const trafficSplitMethod = parseTrafficSplitMethod(
|
const trafficSplitMethod = parseTrafficSplitMethod(
|
||||||
core.getInput('traffic-split-method', {required: true})
|
core.getInput('traffic-split-method', {required: true})
|
||||||
)
|
)
|
||||||
@@ -36,10 +36,11 @@ export async function deploy(
|
|||||||
kubectl,
|
kubectl,
|
||||||
trafficSplitMethod
|
trafficSplitMethod
|
||||||
)
|
)
|
||||||
|
core.endGroup()
|
||||||
core.debug('Deployed manifest files: ' + deployedManifestFiles)
|
core.debug('Deployed manifest files: ' + deployedManifestFiles)
|
||||||
|
|
||||||
// check manifest stability
|
// check manifest stability
|
||||||
core.info('Checking manifest stability')
|
core.startGroup('Checking manifest stability')
|
||||||
const resourceTypes: Resource[] = getResources(
|
const resourceTypes: Resource[] = getResources(
|
||||||
deployedManifestFiles,
|
deployedManifestFiles,
|
||||||
models.DEPLOYMENT_TYPES.concat([
|
models.DEPLOYMENT_TYPES.concat([
|
||||||
@@ -47,17 +48,19 @@ export async function deploy(
|
|||||||
])
|
])
|
||||||
)
|
)
|
||||||
await checkManifestStability(kubectl, resourceTypes)
|
await checkManifestStability(kubectl, resourceTypes)
|
||||||
|
core.endGroup()
|
||||||
|
|
||||||
if (deploymentStrategy == DeploymentStrategy.BLUE_GREEN) {
|
if (deploymentStrategy == DeploymentStrategy.BLUE_GREEN) {
|
||||||
core.info('Routing blue green')
|
core.startGroup('Routing blue green')
|
||||||
const routeStrategy = parseRouteStrategy(
|
const routeStrategy = parseRouteStrategy(
|
||||||
core.getInput('route-method', {required: true})
|
core.getInput('route-method', {required: true})
|
||||||
)
|
)
|
||||||
await routeBlueGreen(kubectl, inputManifestFiles, routeStrategy)
|
await routeBlueGreen(kubectl, inputManifestFiles, routeStrategy)
|
||||||
|
core.endGroup()
|
||||||
}
|
}
|
||||||
|
|
||||||
// print ingresses
|
// print ingresses
|
||||||
core.info('Printing ingresses')
|
core.startGroup('Printing ingresses')
|
||||||
const ingressResources: Resource[] = getResources(deployedManifestFiles, [
|
const ingressResources: Resource[] = getResources(deployedManifestFiles, [
|
||||||
KubernetesConstants.DiscoveryAndLoadBalancerResource.INGRESS
|
KubernetesConstants.DiscoveryAndLoadBalancerResource.INGRESS
|
||||||
])
|
])
|
||||||
@@ -67,9 +70,10 @@ export async function deploy(
|
|||||||
ingressResource.name
|
ingressResource.name
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
core.endGroup()
|
||||||
|
|
||||||
// annotate resources
|
// annotate resources
|
||||||
core.info('Annotating resources')
|
core.startGroup('Annotating resources')
|
||||||
let allPods
|
let allPods
|
||||||
try {
|
try {
|
||||||
allPods = JSON.parse((await kubectl.getAllPods()).stdout)
|
allPods = JSON.parse((await kubectl.getAllPods()).stdout)
|
||||||
@@ -82,4 +86,5 @@ export async function deploy(
|
|||||||
resourceTypes,
|
resourceTypes,
|
||||||
allPods
|
allPods
|
||||||
)
|
)
|
||||||
|
core.endGroup()
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-8
@@ -65,26 +65,30 @@ async function promoteCanary(kubectl: Kubectl, manifests: string[]) {
|
|||||||
|
|
||||||
// In case of SMI traffic split strategy when deployment is promoted, first we will redirect traffic to
|
// In case of SMI traffic split strategy when deployment is promoted, first we will redirect traffic to
|
||||||
// canary deployment, then update stable deployment and then redirect traffic to stable deployment
|
// canary deployment, then update stable deployment and then redirect traffic to stable deployment
|
||||||
core.info('Redirecting traffic to canary deployment')
|
core.startGroup('Redirecting traffic to canary deployment')
|
||||||
await SMICanaryDeploymentHelper.redirectTrafficToCanaryDeployment(
|
await SMICanaryDeploymentHelper.redirectTrafficToCanaryDeployment(
|
||||||
kubectl,
|
kubectl,
|
||||||
manifests
|
manifests
|
||||||
)
|
)
|
||||||
|
core.endGroup()
|
||||||
|
|
||||||
core.info('Deploying input manifests with SMI canary strategy')
|
core.startGroup('Deploying input manifests with SMI canary strategy')
|
||||||
await deploy.deploy(kubectl, manifests, DeploymentStrategy.CANARY)
|
await deploy.deploy(kubectl, manifests, DeploymentStrategy.CANARY)
|
||||||
|
core.endGroup()
|
||||||
|
|
||||||
core.info('Redirecting traffic to stable deployment')
|
core.startGroup('Redirecting traffic to stable deployment')
|
||||||
await SMICanaryDeploymentHelper.redirectTrafficToStableDeployment(
|
await SMICanaryDeploymentHelper.redirectTrafficToStableDeployment(
|
||||||
kubectl,
|
kubectl,
|
||||||
manifests
|
manifests
|
||||||
)
|
)
|
||||||
|
core.endGroup()
|
||||||
} else {
|
} else {
|
||||||
core.info('Deploying input manifests')
|
core.startGroup('Deploying input manifests')
|
||||||
await deploy.deploy(kubectl, manifests, DeploymentStrategy.CANARY)
|
await deploy.deploy(kubectl, manifests, DeploymentStrategy.CANARY)
|
||||||
|
core.endGroup()
|
||||||
}
|
}
|
||||||
|
|
||||||
core.info('Deleting canary and baseline workloads')
|
core.startGroup('Deleting canary and baseline workloads')
|
||||||
try {
|
try {
|
||||||
await canaryDeploymentHelper.deleteCanaryDeployment(
|
await canaryDeploymentHelper.deleteCanaryDeployment(
|
||||||
kubectl,
|
kubectl,
|
||||||
@@ -97,6 +101,7 @@ async function promoteCanary(kubectl: Kubectl, manifests: string[]) {
|
|||||||
ex
|
ex
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
core.endGroup()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function promoteBlueGreen(kubectl: Kubectl, manifests: string[]) {
|
async function promoteBlueGreen(kubectl: Kubectl, manifests: string[]) {
|
||||||
@@ -109,7 +114,7 @@ async function promoteBlueGreen(kubectl: Kubectl, manifests: string[]) {
|
|||||||
core.getInput('route-method', {required: true})
|
core.getInput('route-method', {required: true})
|
||||||
)
|
)
|
||||||
|
|
||||||
core.info('Deleting old deployment and making new one')
|
core.startGroup('Deleting old deployment and making new one')
|
||||||
let result
|
let result
|
||||||
if (routeStrategy == RouteStrategy.INGRESS) {
|
if (routeStrategy == RouteStrategy.INGRESS) {
|
||||||
result = await promoteBlueGreenIngress(kubectl, manifestObjects)
|
result = await promoteBlueGreenIngress(kubectl, manifestObjects)
|
||||||
@@ -118,9 +123,10 @@ async function promoteBlueGreen(kubectl: Kubectl, manifests: string[]) {
|
|||||||
} else {
|
} else {
|
||||||
result = await promoteBlueGreenService(kubectl, manifestObjects)
|
result = await promoteBlueGreenService(kubectl, manifestObjects)
|
||||||
}
|
}
|
||||||
|
core.endGroup()
|
||||||
|
|
||||||
// checking stability of newly created deployments
|
// checking stability of newly created deployments
|
||||||
core.info('Checking manifest stability')
|
core.startGroup('Checking manifest stability')
|
||||||
const deployedManifestFiles = result.newFilePaths
|
const deployedManifestFiles = result.newFilePaths
|
||||||
const resources: Resource[] = getResources(
|
const resources: Resource[] = getResources(
|
||||||
deployedManifestFiles,
|
deployedManifestFiles,
|
||||||
@@ -129,8 +135,9 @@ async function promoteBlueGreen(kubectl: Kubectl, manifests: string[]) {
|
|||||||
])
|
])
|
||||||
)
|
)
|
||||||
await KubernetesManifestUtility.checkManifestStability(kubectl, resources)
|
await KubernetesManifestUtility.checkManifestStability(kubectl, resources)
|
||||||
|
core.endGroup()
|
||||||
|
|
||||||
core.info(
|
core.startGroup(
|
||||||
'Routing to new deployments and deleting old workloads and services'
|
'Routing to new deployments and deleting old workloads and services'
|
||||||
)
|
)
|
||||||
if (routeStrategy == RouteStrategy.INGRESS) {
|
if (routeStrategy == RouteStrategy.INGRESS) {
|
||||||
@@ -170,4 +177,5 @@ async function promoteBlueGreen(kubectl: Kubectl, manifests: string[]) {
|
|||||||
manifestObjects.deploymentEntityList
|
manifestObjects.deploymentEntityList
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
core.endGroup()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,24 +36,26 @@ async function rejectCanary(kubectl: Kubectl, manifests: string[]) {
|
|||||||
core.getInput('traffic-split-method', {required: true})
|
core.getInput('traffic-split-method', {required: true})
|
||||||
)
|
)
|
||||||
if (trafficSplitMethod == TrafficSplitMethod.SMI) {
|
if (trafficSplitMethod == TrafficSplitMethod.SMI) {
|
||||||
core.info('Rejecting deployment with SMI canary strategy')
|
core.startGroup('Rejecting deployment with SMI canary strategy')
|
||||||
includeServices = true
|
includeServices = true
|
||||||
await SMICanaryDeploymentHelper.redirectTrafficToStableDeployment(
|
await SMICanaryDeploymentHelper.redirectTrafficToStableDeployment(
|
||||||
kubectl,
|
kubectl,
|
||||||
manifests
|
manifests
|
||||||
)
|
)
|
||||||
|
core.endGroup()
|
||||||
}
|
}
|
||||||
|
|
||||||
core.info('Deleting baseline and canary workloads')
|
core.startGroup('Deleting baseline and canary workloads')
|
||||||
await canaryDeploymentHelper.deleteCanaryDeployment(
|
await canaryDeploymentHelper.deleteCanaryDeployment(
|
||||||
kubectl,
|
kubectl,
|
||||||
manifests,
|
manifests,
|
||||||
includeServices
|
includeServices
|
||||||
)
|
)
|
||||||
|
core.endGroup()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function rejectBlueGreen(kubectl: Kubectl, manifests: string[]) {
|
async function rejectBlueGreen(kubectl: Kubectl, manifests: string[]) {
|
||||||
core.info('Rejecting deployment with blue green strategy')
|
core.startGroup('Rejecting deployment with blue green strategy')
|
||||||
|
|
||||||
const routeStrategy = parseRouteStrategy(
|
const routeStrategy = parseRouteStrategy(
|
||||||
core.getInput('route-method', {required: true})
|
core.getInput('route-method', {required: true})
|
||||||
@@ -65,4 +67,5 @@ async function rejectBlueGreen(kubectl: Kubectl, manifests: string[]) {
|
|||||||
} else {
|
} else {
|
||||||
await rejectBlueGreenService(kubectl, manifests)
|
await rejectBlueGreenService(kubectl, manifests)
|
||||||
}
|
}
|
||||||
|
core.endGroup()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ import {parseRouteStrategy, RouteStrategy} from '../types/routeStrategy'
|
|||||||
import {ExecOutput} from '@actions/exec'
|
import {ExecOutput} from '@actions/exec'
|
||||||
import {
|
import {
|
||||||
getWorkflowAnnotationKeyLabel,
|
getWorkflowAnnotationKeyLabel,
|
||||||
getWorkflowAnnotations
|
getWorkflowAnnotations,
|
||||||
|
cleanLabel
|
||||||
} from '../utilities/workflowAnnotationUtils'
|
} from '../utilities/workflowAnnotationUtils'
|
||||||
import {
|
import {
|
||||||
annotateChildPods,
|
annotateChildPods,
|
||||||
@@ -70,10 +71,7 @@ export async function deployManifests(
|
|||||||
return newFilePaths
|
return newFilePaths
|
||||||
}
|
}
|
||||||
|
|
||||||
case undefined: {
|
case DeploymentStrategy.BASIC: {
|
||||||
core.warning('Deployment strategy is not recognized.')
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
const trafficSplitMethod = parseTrafficSplitMethod(
|
const trafficSplitMethod = parseTrafficSplitMethod(
|
||||||
core.getInput('traffic-split-method', {required: true})
|
core.getInput('traffic-split-method', {required: true})
|
||||||
)
|
)
|
||||||
@@ -94,6 +92,10 @@ export async function deployManifests(
|
|||||||
|
|
||||||
return files
|
return files
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
throw new Error('Deployment strategy is not recognized.')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,10 +215,10 @@ async function labelResources(
|
|||||||
label: string
|
label: string
|
||||||
) {
|
) {
|
||||||
const labels = [
|
const labels = [
|
||||||
`workflowFriendlyName=${normalizeWorkflowStrLabel(
|
`workflowFriendlyName=${cleanLabel(
|
||||||
process.env.GITHUB_WORKFLOW
|
normalizeWorkflowStrLabel(process.env.GITHUB_WORKFLOW)
|
||||||
)}`,
|
)}`,
|
||||||
`workflow=${label}`
|
`workflow=${cleanLabel(label)}`
|
||||||
]
|
]
|
||||||
|
|
||||||
checkForErrors([await kubectl.labelFiles(files, labels)], true)
|
checkForErrors([await kubectl.labelFiles(files, labels)], true)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ describe('Deployment strategy type', () => {
|
|||||||
const vals = <any>Object.values(DeploymentStrategy)
|
const vals = <any>Object.values(DeploymentStrategy)
|
||||||
expect(vals.includes('canary')).toBe(true)
|
expect(vals.includes('canary')).toBe(true)
|
||||||
expect(vals.includes('blue-green')).toBe(true)
|
expect(vals.includes('blue-green')).toBe(true)
|
||||||
|
expect(vals.includes('basic')).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('it can parse valid values from a string', () => {
|
test('it can parse valid values from a string', () => {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export enum DeploymentStrategy {
|
export enum DeploymentStrategy {
|
||||||
|
BASIC = 'basic',
|
||||||
CANARY = 'canary',
|
CANARY = 'canary',
|
||||||
BLUE_GREEN = 'blue-green'
|
BLUE_GREEN = 'blue-green'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
import {prefixObjectKeys} from '../utilities/workflowAnnotationUtils'
|
import {
|
||||||
|
cleanLabel,
|
||||||
|
prefixObjectKeys
|
||||||
|
} from '../utilities/workflowAnnotationUtils'
|
||||||
|
|
||||||
describe('WorkflowAnnotationUtils', () => {
|
describe('WorkflowAnnotationUtils', () => {
|
||||||
describe('prefixObjectKeys', () => {
|
describe('prefixObjectKeys', () => {
|
||||||
@@ -15,4 +18,16 @@ describe('WorkflowAnnotationUtils', () => {
|
|||||||
expect(prefixObjectKeys(obj, prefix)).toEqual(expected)
|
expect(prefixObjectKeys(obj, prefix)).toEqual(expected)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('cleanLabel', () => {
|
||||||
|
it('should clean label', () => {
|
||||||
|
const alreadyClean = 'alreadyClean'
|
||||||
|
expect(cleanLabel(alreadyClean)).toEqual(alreadyClean)
|
||||||
|
expect(cleanLabel('.startInvalid')).toEqual('startInvalid')
|
||||||
|
expect(cleanLabel('with%S0ME&invalid#chars')).toEqual(
|
||||||
|
'withS0MEinvalidchars'
|
||||||
|
)
|
||||||
|
expect(cleanLabel('with⚒️emoji')).toEqual('withemoji')
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -47,3 +47,14 @@ export function getWorkflowAnnotationKeyLabel(
|
|||||||
.digest('hex')
|
.digest('hex')
|
||||||
return `githubWorkflow_${hashKey}`
|
return `githubWorkflow_${hashKey}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans label to match valid kubernetes label specification by removing invalid characters
|
||||||
|
* @param label
|
||||||
|
* @returns cleaned label
|
||||||
|
*/
|
||||||
|
export function cleanLabel(label: string): string {
|
||||||
|
const removedInvalidChars = label.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