Compare commits

..

1 Commits

Author SHA1 Message Date
GitHub Action 921d6c4ef8 build 2023-11-06 17:46:12 +00:00
16 changed files with 31208 additions and 3163 deletions
+4 -7
View File
@@ -10,13 +10,10 @@ jobs:
CodeQL-Build:
# CodeQL runs on ubuntu-latest and windows-latest
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1
uses: actions/checkout@v3
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
@@ -24,7 +21,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@05963f47d870e2cb19a537396c1f668a348c7d8f #v3.24.8
uses: github/codeql-action/init@v2
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
@@ -32,7 +29,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@05963f47d870e2cb19a537396c1f668a348c7d8f #v3.24.8
uses: github/codeql-action/autobuild@v2
# ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -46,4 +43,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@05963f47d870e2cb19a537396c1f668a348c7d8f #v3.24.8
uses: github/codeql-action/analyze@v2
+2 -5
View File
@@ -1,4 +1,4 @@
name: Release Project
name: release Project
on:
push:
@@ -10,9 +10,6 @@ on:
jobs:
release:
permissions:
actions: read
contents: write
uses: Azure/action-release-workflows/.github/workflows/release_js_project.yaml@v1
uses: Azure/action-release-workflows/.github/workflows/release_js_project.yaml@81e6a8ed41ced9d131dea884ecae7b8c6dc4f799
with:
changelogPath: ./CHANGELOG.md
@@ -43,7 +43,7 @@ jobs:
run: |
set +x
# create cluster
az group create --location eastus2 --name ${{ env.NAMESPACE }}
az group create --location eastus --name ${{ env.NAMESPACE }}
az aks create --name ${{ env.NAMESPACE }} --resource-group ${{ env.NAMESPACE }} --enable-private-cluster --generate-ssh-keys
az aks get-credentials --resource-group ${{ env.NAMESPACE }} --name ${{ env.NAMESPACE }}
@@ -63,7 +63,6 @@ jobs:
images: nginx:1.14.2
manifests: |
test/integration/manifests/test.yml
test/integration/manifests/test2.yml
action: deploy
private-cluster: true
resource-group: ${{ env.NAMESPACE }}
@@ -74,9 +73,6 @@ jobs:
python test/integration/k8s-deploy-test.py private=${{ env.NAMESPACE }} namespace=${{ env.NAMESPACE }} kind=Deployment name=nginx-deployment containerName=nginx:1.14.2 labels=app:nginx,workflow:actions.github.com-k8s-deploy,workflowFriendlyName:Cluster_Integration_Tests_-_private_cluster selectorLabels=app:nginx
python test/integration/k8s-deploy-test.py private=${{ env.NAMESPACE }} namespace=${{ env.NAMESPACE }} kind=Service name=nginx-service labels=workflow:actions.github.com-k8s-deploy,workflowFriendlyName:Cluster_Integration_Tests_-_private_cluster selectorLabels=app:nginx
python test/integration/k8s-deploy-test.py private=${{ env.NAMESPACE }} namespace=${{ env.NAMESPACE }} kind=Deployment name=nginx-deployment2 containerName=nginx:1.14.2 labels=app:nginx2,workflow:actions.github.com-k8s-deploy,workflowFriendlyName:Cluster_Integration_Tests_-_private_cluster selectorLabels=app:nginx2
python test/integration/k8s-deploy-test.py private=${{ env.NAMESPACE }} namespace=${{ env.NAMESPACE }} kind=Service name=nginx-service2 labels=workflow:actions.github.com-k8s-deploy,workflowFriendlyName:Cluster_Integration_Tests_-_private_cluster selectorLabels=app:nginx2
- name: Clean up AKS cluster
if: ${{ always() }}
run: |
+10
View File
@@ -0,0 +1,10 @@
name: Tag and create release draft
on:
push:
branches:
- releases/*
jobs:
tag-and-release:
uses: OliverMKing/javascript-release-workflow/.github/workflows/tag-and-release.yml@main
-1
View File
@@ -2,6 +2,5 @@ node_modules
.DS_Store
.idea
lib/
coverage/
-17
View File
@@ -1,22 +1,5 @@
# Changelog
## [5.0.0] - 2024-03-12
### Changed
- #309 Updated to Node20 and upgraded release workflows to @v1 tag
- #306 update release workflow to use new prefix, remove deprecated release
- #303 fix: ensure imageNames are not empty strings
- #299 bump release workflow sha
- #298 bump minikube to fix runner deps
- #297 update release workflow
### Added
- #304 add v prefix for version tagging
- #302 adding ncc to build
- #301 adding release workflow artifact fix
## [4.10.0] - 2023-10-30
### Added
+23 -23
View File
@@ -132,7 +132,7 @@ Following are the key capabilities of this action:
### Basic deployment (without any deployment strategy)
```yaml
- uses: Azure/k8s-deploy@v5
- uses: Azure/k8s-deploy@v4
with:
namespace: 'myapp'
manifests: |
@@ -146,7 +146,7 @@ Following are the key capabilities of this action:
### Private cluster deployment
```yaml
- uses: Azure/k8s-deploy@v5
- uses: Azure/k8s-deploy@v4
with:
resource-group: yourResourceGroup
name: yourClusterName
@@ -166,7 +166,7 @@ Following are the key capabilities of this action:
### Canary deployment without service mesh
```yaml
- uses: Azure/k8s-deploy@v5
- uses: Azure/k8s-deploy@v4
with:
namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
@@ -185,7 +185,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@v5
- uses: Azure/k8s-deploy@v4
with:
namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
@@ -203,7 +203,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@v5
- uses: Azure/k8s-deploy@v4
with:
namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
@@ -224,7 +224,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@v5
- uses: Azure/k8s-deploy@v4
with:
namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }} '
@@ -243,7 +243,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@v5
- uses: Azure/k8s-deploy@v4
with:
namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
@@ -263,7 +263,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@v5
- uses: Azure/k8s-deploy@v4
with:
namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
@@ -292,7 +292,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@master
- uses: Azure/docker-login@v1
with:
@@ -304,23 +304,23 @@ jobs:
docker build . -t contoso.azurecr.io/k8sdemo:${{ github.sha }}
docker push contoso.azurecr.io/k8sdemo:${{ github.sha }}
- uses: azure/setup-kubectl@v4
- uses: azure/setup-kubectl@v2.0
# Set the target AKS cluster.
- uses: Azure/aks-set-context@v4
- uses: Azure/aks-set-context@v1
with:
creds: '${{ secrets.AZURE_CREDENTIALS }}'
cluster-name: contoso
resource-group: contoso-rg
- uses: Azure/k8s-create-secret@v4
- uses: Azure/k8s-create-secret@v1.1
with:
container-registry-url: contoso.azurecr.io
container-registry-username: ${{ secrets.REGISTRY_USERNAME }}
container-registry-password: ${{ secrets.REGISTRY_PASSWORD }}
secret-name: demo-k8s-secret
- uses: Azure/k8s-deploy@v5
- uses: Azure/k8s-deploy@v4
with:
action: deploy
manifests: |
@@ -341,7 +341,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@master
- uses: Azure/docker-login@v1
with:
@@ -353,13 +353,13 @@ jobs:
docker build . -t contoso.azurecr.io/k8sdemo:${{ github.sha }}
docker push contoso.azurecr.io/k8sdemo:${{ github.sha }}
- uses: azure/setup-kubectl@v4
- uses: azure/setup-kubectl@v2.0
- uses: Azure/k8s-set-context@v4
- uses: Azure/k8s-set-context@v2
with:
kubeconfig: ${{ secrets.KUBE_CONFIG }}
- uses: Azure/k8s-create-secret@v4
- uses: Azure/k8s-create-secret@v1.1
with:
container-registry-url: contoso.azurecr.io
container-registry-username: ${{ secrets.REGISTRY_USERNAME }}
@@ -391,7 +391,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@master
- uses: Azure/docker-login@v1
with:
@@ -423,16 +423,16 @@ jobs:
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- uses: azure/setup-kubectl@v4
- uses: azure/setup-kubectl@v2.0
# Set the target AKS cluster.
- uses: Azure/aks-set-context@v4
- uses: Azure/aks-set-context@v1
with:
creds: '${{ secrets.AZURE_CREDENTIALS }}'
cluster-name: contoso
resource-group: contoso-rg
- uses: Azure/k8s-create-secret@v4
- uses: Azure/k8s-create-secret@v1.1
with:
namespace: ${{ env.NAMESPACE }}
container-registry-url: contoso.azurecr.io
@@ -440,7 +440,7 @@ jobs:
container-registry-password: ${{ secrets.REGISTRY_PASSWORD }}
secret-name: demo-k8s-secret
- uses: azure/k8s-bake@v3
- uses: azure/k8s-bake@v2
with:
renderEngine: 'helm'
helmChart: './aks-helloworld/'
@@ -450,7 +450,7 @@ jobs:
helm-version: 'latest'
id: bake
- uses: Azure/k8s-deploy@v5
- uses: Azure/k8s-deploy@v1.2
with:
action: deploy
manifests: ${{ steps.bake.outputs.manifestsBundle }}
+1 -1
View File
@@ -84,5 +84,5 @@ inputs:
branding:
color: 'green'
runs:
using: 'node20'
using: 'node16'
main: 'lib/index.js'
+24128
View File
File diff suppressed because one or more lines are too long
+6964 -2983
View File
File diff suppressed because it is too large Load Diff
+7 -8
View File
@@ -1,11 +1,10 @@
{
"name": "k8s-deploy-action",
"version": "5.0.0",
"version": "0.0.0",
"author": "Deepak Sattiraju",
"license": "MIT",
"scripts": {
"prebuild": "npm i @vercel/ncc",
"build": "ncc build src/run.ts -o lib",
"build": "npm i ncc && npx ncc build src/run.ts -o lib",
"test": "jest",
"coverage": "jest --coverage=true",
"format": "prettier --write .",
@@ -20,16 +19,16 @@
"@octokit/plugin-retry": "^3.0.9",
"@types/minipass": "^3.1.2",
"js-yaml": "3.13.1",
"minimist": "^1.2.8"
"ncc": "^0.3.6"
},
"devDependencies": {
"@types/jest": "^26.0.0",
"@types/js-yaml": "^3.12.7",
"@types/node": "^12.20.41",
"@vercel/ncc": "^0.36.1",
"jest": "^29.7.0",
"prettier": "^2.8.8",
"ts-jest": "^29.2.3",
"typescript": "5.5.4"
"jest": "^26.0.0",
"prettier": "^2.7.1",
"ts-jest": "^26.0.0",
"typescript": "3.9.5"
}
}
+11
View File
@@ -39,6 +39,17 @@ const testNamespace = 'testNamespace'
const defaultNamespace = 'default'
const otherNamespace = 'otherns'
describe('Kubectl class', () => {
describe('default namespace behavior', () => {
const kubectl = new Kubectl(kubectlPath, defaultNamespace)
const execReturn = {exitCode: 0, stdout: 'Output', stderr: ''}
beforeEach(() => {
jest.spyOn(exec, 'getExecOutput').mockImplementation(async () => {
return execReturn
})
})
})
describe('with a success exec return in testNamespace', () => {
const kubectl = new Kubectl(kubectlPath, testNamespace)
const execReturn = {exitCode: 0, stdout: 'Output', stderr: ''}
+4 -18
View File
@@ -1,12 +1,8 @@
import {
PrivateKubectl,
extractFileNames,
replaceFileNamesWithBaseNames
} from './privatekubectl'
import {PrivateKubectl} from './privatekubectl'
import * as exec from '@actions/exec'
describe('Private kubectl', () => {
const testString = `kubectl annotate -f testdir/test.yml,test2.yml,testdir/subdir/test3.yml -f test4.yml --filename test5.yml actions.github.com/k8s-deploy={"run":"3498366832","repository":"jaiveerk/k8s-deploy","workflow":"Minikube Integration Tests - private cluster","workflowFileName":"run-integration-tests-private.yml","jobName":"run-integration-test","createdBy":"jaiveerk","runUri":"https://github.com/jaiveerk/k8s-deploy/actions/runs/3498366832","commit":"c63b323186ea1320a31290de6dcc094c06385e75","lastSuccessRunCommit":"NA","branch":"refs/heads/main","deployTimestamp":1668787848577,"dockerfilePaths":{"nginx:1.14.2":""},"manifestsPaths":["https://github.com/jaiveerk/k8s-deploy/blob/c63b323186ea1320a31290de6dcc094c06385e75/test/integration/manifests/test.yml"],"helmChartPaths":[],"provider":"GitHub"} --overwrite --namespace test-3498366832`
const testString = `kubectl annotate -f test.yml,test2.yml,test3.yml -f test4.yml --filename test5.yml actions.github.com/k8s-deploy={"run":"3498366832","repository":"jaiveerk/k8s-deploy","workflow":"Minikube Integration Tests - private cluster","workflowFileName":"run-integration-tests-private.yml","jobName":"run-integration-test","createdBy":"jaiveerk","runUri":"https://github.com/jaiveerk/k8s-deploy/actions/runs/3498366832","commit":"c63b323186ea1320a31290de6dcc094c06385e75","lastSuccessRunCommit":"NA","branch":"refs/heads/main","deployTimestamp":1668787848577,"dockerfilePaths":{"nginx:1.14.2":""},"manifestsPaths":["https://github.com/jaiveerk/k8s-deploy/blob/c63b323186ea1320a31290de6dcc094c06385e75/test/integration/manifests/test.yml"],"helmChartPaths":[],"provider":"GitHub"} --overwrite --namespace test-3498366832`
const mockKube = new PrivateKubectl(
'kubectlPath',
'namespace',
@@ -16,18 +12,8 @@ describe('Private kubectl', () => {
)
it('should extract filenames correctly', () => {
expect(extractFileNames(testString)).toEqual([
'testdir/test.yml',
'test2.yml',
'testdir/subdir/test3.yml',
'test4.yml',
'test5.yml'
])
})
it('should replace filenames with basenames correctly', () => {
expect(replaceFileNamesWithBaseNames(testString)).toEqual(
`kubectl annotate -f test.yml,test2.yml,test3.yml -f test4.yml --filename test5.yml actions.github.com/k8s-deploy={"run":"3498366832","repository":"jaiveerk/k8s-deploy","workflow":"Minikube Integration Tests - private cluster","workflowFileName":"run-integration-tests-private.yml","jobName":"run-integration-test","createdBy":"jaiveerk","runUri":"https://github.com/jaiveerk/k8s-deploy/actions/runs/3498366832","commit":"c63b323186ea1320a31290de6dcc094c06385e75","lastSuccessRunCommit":"NA","branch":"refs/heads/main","deployTimestamp":1668787848577,"dockerfilePaths":{"nginx:1.14.2":""},"manifestsPaths":["https://github.com/jaiveerk/k8s-deploy/blob/c63b323186ea1320a31290de6dcc094c06385e75/test/integration/manifests/test.yml"],"helmChartPaths":[],"provider":"GitHub"} --overwrite --namespace test-3498366832`
expect(mockKube.extractFilesnames(testString)).toEqual(
'test.yml test2.yml test3.yml test4.yml test5.yml'
)
})
+52 -57
View File
@@ -19,7 +19,7 @@ export class PrivateKubectl extends Kubectl {
if (this.containsFilenames(kubectlCmd)) {
// For private clusters, files will referenced solely by their basename
kubectlCmd = replaceFileNamesWithBaseNames(kubectlCmd)
kubectlCmd = this.replaceFilnamesWithBasenames(kubectlCmd)
addFileFlag = true
}
@@ -43,21 +43,21 @@ export class PrivateKubectl extends Kubectl {
]
if (addFileFlag) {
const filenames = extractFileNames(kubectlCmd)
const filenames = this.extractFilesnames(kubectlCmd).split(' ')
const tempDirectory =
process.env['runner.tempDirectory'] || os.tmpdir() + '/manifests'
eo.cwd = tempDirectory
privateClusterArgs.push(...['--file', '.'])
for (const filename of filenames) {
try {
this.moveFileToTempManifestDir(filename)
} catch (e) {
core.debug(
`Error moving file ${filename} to temp directory: ${e}`
)
let filenamesArr = filenames[0].split(',')
for (let index = 0; index < filenamesArr.length; index++) {
const file = filenamesArr[index]
if (!file) {
continue
}
this.moveFileToTempManifestDir(file)
}
}
@@ -95,6 +95,49 @@ export class PrivateKubectl extends Kubectl {
} as ExecOutput
}
private replaceFilnamesWithBasenames(kubectlCmd: string) {
let exFilenames = this.extractFilesnames(kubectlCmd)
let filenames = exFilenames.split(' ')
let filenamesArr = filenames[0].split(',')
for (let index = 0; index < filenamesArr.length; index++) {
filenamesArr[index] = path.basename(filenamesArr[index])
}
let baseFilenames = filenamesArr.join()
let result = kubectlCmd.replace(exFilenames, baseFilenames)
return result
}
public extractFilesnames(strToParse: string) {
const fileNames: string[] = []
const argv = minimist(strToParse.split(' '))
const fArg = 'f'
const filenameArg = 'filename'
fileNames.push(...this.extractFilesFromMinimist(argv, fArg))
fileNames.push(...this.extractFilesFromMinimist(argv, filenameArg))
return fileNames.join(' ')
}
private extractFilesFromMinimist(argv, arg: string): string[] {
if (!argv[arg]) {
return []
}
const toReturn: string[] = []
if (typeof argv[arg] === 'string') {
toReturn.push(...argv[arg].split(','))
} else {
for (const value of argv[arg] as string[]) {
toReturn.push(...value.split(','))
}
}
return toReturn
}
private containsFilenames(str: string) {
return str.includes('-f ') || str.includes('filename ')
}
@@ -138,51 +181,3 @@ export class PrivateKubectl extends Kubectl {
})
}
}
export function replaceFileNamesWithBaseNames(kubectlCmd: string) {
let filenames = extractFileNames(kubectlCmd)
let basenames = filenames.map((filename) => path.basename(filename))
let result = kubectlCmd
if (filenames.length != basenames.length) {
throw Error(
'replacing filenames with basenames, ' +
filenames.length +
' filenames != ' +
basenames.length +
'basenames'
)
}
for (let index = 0; index < filenames.length; index++) {
result = result.replace(filenames[index], basenames[index])
}
return result
}
export function extractFileNames(strToParse: string) {
const fileNames: string[] = []
const argv = minimist(strToParse.split(' '))
const fArg = 'f'
const filenameArg = 'filename'
fileNames.push(...extractFilesFromMinimist(argv, fArg))
fileNames.push(...extractFilesFromMinimist(argv, filenameArg))
return fileNames
}
export function extractFilesFromMinimist(argv, arg: string): string[] {
if (!argv[arg]) {
return []
}
const toReturn: string[] = []
if (typeof argv[arg] === 'string') {
toReturn.push(...argv[arg].split(','))
} else {
for (const value of argv[arg] as string[]) {
toReturn.push(...value.split(','))
}
}
return toReturn
}
+1 -5
View File
@@ -23,11 +23,7 @@ export async function getDeploymentConfig(): Promise<DeploymentConfig> {
)
}
const imageNames =
core
.getInput('images')
.split('\n')
.filter((image) => image.length > 0) || []
const imageNames = core.getInput('images').split('\n') || []
const imageDockerfilePathMap: {[id: string]: string} = {}
const pullImages = !(core.getInput('pull-images').toLowerCase() === 'false')
-33
View File
@@ -1,33 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment2
labels:
app: nginx2
spec:
replicas: 1
selector:
matchLabels:
app: nginx2
template:
metadata:
labels:
app: nginx2
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service2
spec:
selector:
app: nginx2
ports:
- protocol: TCP
port: 80
targetPort: 80