Compare commits

..

21 Commits

Author SHA1 Message Date
David Gamero ffc0477133 prettier 2024-07-25 19:31:19 +00:00
David Gamero 56ea81fd08 upgrade to typescript 5 2024-07-25 19:20:36 +00:00
Jaiveer Katariya 00795b0b56 Private Cluster Bugfix - Issue with Multiple Files (#325)
* changed ubuntu runner

* changed minikube action

* Version formatting

* nonedriveR

* update kube version

* installing conntrack'

* updated other actions

* update bg ingress api version

* prettify

* updated ingress backend for new api version

* Added path type

* prettify

* added logging

* added try catch logic to prevent future failures if annotations fail since failing annotations shouldn't affect users

* added nullcheck

* Added fallback filename if workflow fails to get github filepath due to runner issues

* cleanup

* added oliver's feedback + unit test demonstrating regex glitch and fix

* no longer using blank string for failed regex

* add tests and dont split so much

* testing

* file fix

* without fix

* Revert "without fix"

This reverts commit 8da79a8190.

* fixing labels test

* pretty

---------

Co-authored-by: David Gamero <david340804@gmail.com>
2024-07-25 14:47:27 -04:00
David Gamero d565a17533 Update package.json (#317) 2024-03-19 18:36:57 -04:00
David Gamero 1811836de2 create v5 node20 release (#316)
* Update package.json

* Update release-pr.yml

* Update CHANGELOG.md

* Update CHANGELOG.md

* Update CHANGELOG.md

* format

* Update codeql.yml

* Update codeql.yml

* Update codeql.yml

* Update codeql.yml

* format

* update the current tags

* Update codeql.yml

* Update CHANGELOG.md

* Update CHANGELOG.md

* Update codeql.yml
2024-03-19 17:27:31 -04:00
Martin Kraus Larsen 10d9433b15 Update action.yml (#309)
Fix warning like: Node.js 16 actions are deprecated. Please update the following actions to use Node.js 20:
2024-03-12 14:59:19 +00:00
Morten Linderud 52dfbef986 fix: ensure imageNames are not empty strings (#303)
In Typescript/Javascript an empty string split on newline is going to
produce an array with an empty string.

    => "".split('\n')
    [""]

This causes the action to produce a warning, unless `pull-images` is set
to false.

    Failed to get dockerfile path for image : Error: The process '/usr/bin/docker' failed with exit code 1

Filtering the list to remove any zero-length strings from the array
solves this issue.

Signed-off-by: Morten Linderud <morten.linderud@nrk.no>
2024-02-05 15:04:16 -05:00
David Gamero 074d812926 update release workflow to use new prefix, remove deprecated release workflow (#306) 2023-12-08 01:00:22 +00:00
David Gamero e10b599478 update version to v prefix (#304) 2023-12-01 15:49:35 -05:00
David Gamero 93550c22f0 add installing ncc to build (#302)
* add installing ncc to build

* include npx to get to bin link
2023-11-06 12:44:42 -05:00
David Gamero 1fea8281df add release worklflow artiact fix (#301) 2023-11-06 12:11:50 -05:00
David Gamero 1b1edcdfc7 bump release workflow sha (#299) 2023-10-31 13:30:03 -04:00
dependabot[bot] 8cbe18c310 Bump decode-uri-component from 0.2.0 to 0.2.2 (#269)
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: David Gamero <david340804@gmail.com>
2023-10-31 12:35:30 -04:00
dependabot[bot] 8efbc8ba92 Bump json5 from 2.2.1 to 2.2.3 (#275)
Bumps [json5](https://github.com/json5/json5) from 2.2.1 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.1...v2.2.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: David Gamero <david340804@gmail.com>
2023-10-31 16:24:46 +00:00
dependabot[bot] 699a70732d Bump tough-cookie from 4.0.0 to 4.1.3 (#290)
Bumps [tough-cookie](https://github.com/salesforce/tough-cookie) from 4.0.0 to 4.1.3.
- [Release notes](https://github.com/salesforce/tough-cookie/releases)
- [Changelog](https://github.com/salesforce/tough-cookie/blob/master/CHANGELOG.md)
- [Commits](https://github.com/salesforce/tough-cookie/compare/v4.0.0...v4.1.3)

---
updated-dependencies:
- dependency-name: tough-cookie
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: David Gamero <david340804@gmail.com>
2023-10-31 12:19:50 -04:00
dependabot[bot] a1d061da9d Bump semver from 5.7.1 to 5.7.2 (#291)
Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: David Gamero <david340804@gmail.com>
2023-10-31 16:14:24 +00:00
dependabot[bot] 7c36b75ebe Bump word-wrap from 1.2.3 to 1.2.4 (#292)
Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.4.
- [Release notes](https://github.com/jonschlinkert/word-wrap/releases)
- [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4)

---
updated-dependencies:
- dependency-name: word-wrap
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@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>
2023-10-31 16:06:59 +00:00
dependabot[bot] 2f2901757b Bump @babel/traverse from 7.18.9 to 7.23.2 (#295)
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.18.9 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: David Gamero <david340804@gmail.com>
2023-10-31 12:01:40 -04:00
David Gamero 4aba7c26f3 bump minikube to fix runner deps (#298) 2023-10-31 10:25:13 -04:00
David Gamero d6508445a1 release workflow (#297)
* release workflow

* prettier

* switch to azure repo and sha
2023-10-30 16:33:02 -04:00
Bram de Hart a462095a3c Make annotating resources optional (#287)
* Make annotating resources optional

* Clarify descriptions

* Update README

* Refactor retrieving pods

* Remove annotating resources check in deploy.ts

* Add resource annotation integration test

* Move resource annotation integration test to seperate file

* Lint code

* Remove temporary debugging statements

* Fix integration test name

* Fix test

* Abstracting out repeated logic between verifyDeployment and verifyService

* Fix formattin

* Fix reference

* Fix test

* Refactor test

* Update ubuntu version to latest on canary SMI test

* Update ubuntu version to latest on canary SMI test

* Make annotating resources optional

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Clarify descriptions

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Update README

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Refactor retrieving pods

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Remove annotating resources check in deploy.ts

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Add resource annotation integration test

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Move resource annotation integration test to seperate file

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Lint code

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Remove temporary debugging statements

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Fix integration test name

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Fix test

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Abstracting out repeated logic between verifyDeployment and verifyService

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Fix formattin

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Fix reference

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Fix test

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Refactor test

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

* Update ubuntu version to latest on canary SMI test

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>

---------

Signed-off-by: Bram de Hart <bram.dehart@nsgo.nl>
2023-10-16 14:28:01 +00:00
26 changed files with 3329 additions and 30873 deletions
+7 -4
View File
@@ -10,10 +10,13 @@ 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@v3
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
@@ -21,7 +24,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@05963f47d870e2cb19a537396c1f668a348c7d8f #v3.24.8
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
@@ -29,7 +32,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@v2
uses: github/codeql-action/autobuild@05963f47d870e2cb19a537396c1f668a348c7d8f #v3.24.8
# ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -43,4 +46,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@05963f47d870e2cb19a537396c1f668a348c7d8f #v3.24.8
+12 -8
View File
@@ -1,14 +1,18 @@
name: Create release PR
name: Release Project
on:
push:
branches:
- main
paths:
- CHANGELOG.md
workflow_dispatch:
inputs:
release:
description: 'Define release version (ex: v1, v2, v3)'
required: true
jobs:
release-pr:
uses: OliverMKing/javascript-release-workflow/.github/workflows/release-pr.yml@main
release:
permissions:
actions: read
contents: write
uses: Azure/action-release-workflows/.github/workflows/release_js_project.yaml@v1
with:
release: ${{ github.event.inputs.release }}
changelogPath: ./CHANGELOG.md
@@ -38,7 +38,7 @@ jobs:
name: Setup Minikube
uses: medyagh/setup-minikube@latest
with:
minikube-version: 1.24.0
minikube-version: 1.31.2
kubernetes-version: 1.22.3
driver: 'none'
timeout-minutes: 3
@@ -38,7 +38,7 @@ jobs:
name: Setup Minikube
uses: medyagh/setup-minikube@latest
with:
minikube-version: 1.24.0
minikube-version: 1.31.2
kubernetes-version: 1.22.3
driver: 'none'
timeout-minutes: 3
@@ -13,7 +13,7 @@ on:
jobs:
run-integration-test:
name: Run Minikube Integration Tests
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
env:
KUBECONFIG: /home/runner/.kube/config
NAMESPACE: test-${{ github.run_id }}
@@ -43,7 +43,7 @@ jobs:
run: |
set +x
# create cluster
az group create --location eastus --name ${{ env.NAMESPACE }}
az group create --location eastus2 --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,6 +63,7 @@ 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 }}
@@ -73,6 +74,9 @@ 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: |
@@ -0,0 +1,89 @@
name: Minikube Integration Tests - resource annotation
on:
pull_request:
branches:
- main
- 'releases/*'
push:
branches:
- main
- 'releases/*'
workflow_dispatch:
jobs:
run-integration-test:
name: Run Minikube Integration Tests
runs-on: ubuntu-latest
env:
KUBECONFIG: /home/runner/.kube/config
NAMESPACE: test-${{ github.run_id }}
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: |
rm -rf node_modules/
npm install
- name: Install ncc
run: npm i -g @vercel/ncc
- name: Install conntrack
run: sudo apt-get install -y conntrack
- name: Build
run: ncc build src/run.ts -o lib
- uses: Azure/setup-kubectl@v3
name: Install Kubectl
- id: setup-minikube
name: Setup Minikube
uses: medyagh/setup-minikube@latest
with:
minikube-version: 1.24.0
kubernetes-version: 1.22.3
driver: 'none'
timeout-minutes: 3
- name: Create namespace to run tests
run: kubectl create ns ${{ env.NAMESPACE }}
- uses: actions/setup-python@v2
name: Install Python
with:
python-version: '3.x'
- name: Cleaning any previously created items
run: |
python test/integration/k8s-deploy-delete.py 'Service' 'all' ${{ env.NAMESPACE }}
python test/integration/k8s-deploy-delete.py 'Deployment' 'all' ${{ env.NAMESPACE }}
python test/integration/k8s-deploy-delete.py 'Ingress' 'all' ${{ env.NAMESPACE }}
- name: Executing deploy action for pod with resource annotation enabled by default
uses: ./
with:
namespace: ${{ env.NAMESPACE }}
images: nginx:1.14.2
manifests: |
test/integration/manifests/test.yml
action: deploy
- name: Checking if deployments is created with additional resource annotation
run: |
python test/integration/k8s-deploy-test.py namespace=${{ env.NAMESPACE }} kind=Deployment name=nginx-deployment containerName=nginx:1.14.2 labels=app:nginx,workflow:actions.github.com-k8s-deploy,workflowFriendlyName:Minikube_Integration_Tests_-_resource_annotation selectorLabels=app:nginx annotations=actions.github.com/k8s-deploy,deployment.kubernetes.io/revision,kubectl.kubernetes.io/last-applied-configuration
- name: Cleaning previously created deployment
run: |
python test/integration/k8s-deploy-delete.py 'Deployment' 'all' ${{ env.NAMESPACE }}
- name: Executing deploy action for pod with resource annotation disabled
uses: ./
with:
namespace: ${{ env.NAMESPACE }}
images: nginx:1.14.2
manifests: |
test/integration/manifests/test.yml
action: deploy
annotate-resources: false
- name: Checking if deployment is created without additional resource annotation
run: |
python test/integration/k8s-deploy-test.py namespace=${{ env.NAMESPACE }} kind=Deployment name=nginx-deployment containerName=nginx:1.14.2 selectorLabels=app:nginx annotations=deployment.kubernetes.io/revision,kubectl.kubernetes.io/last-applied-configuration
-10
View File
@@ -1,10 +0,0 @@
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,5 +2,6 @@ node_modules
.DS_Store
.idea
lib/
coverage/
+28
View File
@@ -0,0 +1,28 @@
# 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
- #287 Make annotating resources optional
- #283 Fix “Service” route-method of the Blue-Green strategy with some manifest files
- #281 bump codeql to node 16
- #279 upgrade codeql
- #276 Fixes multiple namespaces bug
+28 -24
View File
@@ -113,9 +113,13 @@ 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-resources</br></br>(Optional)</td>
<td>Acceptable values: true/false</br>Default value: true</br>Switch whether to annotate the resources or not. If set to false all annotations are skipped completely.</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>
<td>Acceptable values: true/false</br>Default value: true</br>Switch whether to annotate the namespace resources object or not. Ignored when annotate-resources is set to false.</td>
</tr>
<tr>
<td>skip-tls-verify</br></br>(Optional)</td>
@@ -128,7 +132,7 @@ Following are the key capabilities of this action:
### Basic deployment (without any deployment strategy)
```yaml
- uses: Azure/k8s-deploy@v4
- uses: Azure/k8s-deploy@v5
with:
namespace: 'myapp'
manifests: |
@@ -142,7 +146,7 @@ Following are the key capabilities of this action:
### Private cluster deployment
```yaml
- uses: Azure/k8s-deploy@v4
- uses: Azure/k8s-deploy@v5
with:
resource-group: yourResourceGroup
name: yourClusterName
@@ -162,7 +166,7 @@ Following are the key capabilities of this action:
### Canary deployment without service mesh
```yaml
- uses: Azure/k8s-deploy@v4
- uses: Azure/k8s-deploy@v5
with:
namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
@@ -181,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@v4
- uses: Azure/k8s-deploy@v5
with:
namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
@@ -199,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@v4
- uses: Azure/k8s-deploy@v5
with:
namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
@@ -220,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@v4
- uses: Azure/k8s-deploy@v5
with:
namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }} '
@@ -239,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@v4
- uses: Azure/k8s-deploy@v5
with:
namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
@@ -259,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@v4
- uses: Azure/k8s-deploy@v5
with:
namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
@@ -288,7 +292,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/checkout@v4
- uses: Azure/docker-login@v1
with:
@@ -300,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@v2.0
- uses: azure/setup-kubectl@v4
# Set the target AKS cluster.
- uses: Azure/aks-set-context@v1
- uses: Azure/aks-set-context@v4
with:
creds: '${{ secrets.AZURE_CREDENTIALS }}'
cluster-name: contoso
resource-group: contoso-rg
- uses: Azure/k8s-create-secret@v1.1
- uses: Azure/k8s-create-secret@v4
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@v4
- uses: Azure/k8s-deploy@v5
with:
action: deploy
manifests: |
@@ -337,7 +341,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/checkout@v4
- uses: Azure/docker-login@v1
with:
@@ -349,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@v2.0
- uses: azure/setup-kubectl@v4
- uses: Azure/k8s-set-context@v2
- uses: Azure/k8s-set-context@v4
with:
kubeconfig: ${{ secrets.KUBE_CONFIG }}
- uses: Azure/k8s-create-secret@v1.1
- uses: Azure/k8s-create-secret@v4
with:
container-registry-url: contoso.azurecr.io
container-registry-username: ${{ secrets.REGISTRY_USERNAME }}
@@ -387,7 +391,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/checkout@v4
- uses: Azure/docker-login@v1
with:
@@ -419,16 +423,16 @@ jobs:
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- uses: azure/setup-kubectl@v2.0
- uses: azure/setup-kubectl@v4
# Set the target AKS cluster.
- uses: Azure/aks-set-context@v1
- uses: Azure/aks-set-context@v4
with:
creds: '${{ secrets.AZURE_CREDENTIALS }}'
cluster-name: contoso
resource-group: contoso-rg
- uses: Azure/k8s-create-secret@v1.1
- uses: Azure/k8s-create-secret@v4
with:
namespace: ${{ env.NAMESPACE }}
container-registry-url: contoso.azurecr.io
@@ -436,7 +440,7 @@ jobs:
container-registry-password: ${{ secrets.REGISTRY_PASSWORD }}
secret-name: demo-k8s-secret
- uses: azure/k8s-bake@v2
- uses: azure/k8s-bake@v3
with:
renderEngine: 'helm'
helmChart: './aks-helloworld/'
@@ -446,7 +450,7 @@ jobs:
helm-version: 'latest'
id: bake
- uses: Azure/k8s-deploy@v1.2
- uses: Azure/k8s-deploy@v5
with:
action: deploy
manifests: ${{ steps.bake.outputs.manifestsBundle }}
+6 -2
View File
@@ -59,8 +59,12 @@ inputs:
description: 'Github token'
default: ${{ github.token }}
required: true
annotate-resources:
description: 'Annotate the resources. If set to false all annotations are skipped completely.'
required: false
default: true
annotate-namespace:
description: 'Annotate the target namespace'
description: 'Annotate the target namespace. Ignored when annotate-resources is set to false.'
required: false
default: true
private-cluster:
@@ -80,5 +84,5 @@ inputs:
branding:
color: 'green'
runs:
using: 'node16'
using: 'node20'
main: 'lib/index.js'
-24092
View File
File diff suppressed because one or more lines are too long
+2974 -6593
View File
File diff suppressed because it is too large Load Diff
+9 -7
View File
@@ -1,10 +1,11 @@
{
"name": "k8s-deploy-action",
"version": "0.0.0",
"version": "5.0.0",
"author": "Deepak Sattiraju",
"license": "MIT",
"scripts": {
"build": "npx ncc build src/run.ts -o lib",
"prebuild": "npm i @vercel/ncc",
"build": "ncc build src/run.ts -o lib",
"test": "jest",
"coverage": "jest --coverage=true",
"format": "prettier --write .",
@@ -18,16 +19,17 @@
"@octokit/core": "^3.5.1",
"@octokit/plugin-retry": "^3.0.9",
"@types/minipass": "^3.1.2",
"js-yaml": "3.13.1"
"js-yaml": "3.13.1",
"minimist": "^1.2.8"
},
"devDependencies": {
"@types/jest": "^26.0.0",
"@types/js-yaml": "^3.12.7",
"@types/node": "^12.20.41",
"@vercel/ncc": "^0.36.1",
"jest": "^26.0.0",
"prettier": "^2.7.1",
"ts-jest": "^26.0.0",
"typescript": "3.9.5"
"jest": "^29.7.0",
"prettier": "^2.8.8",
"ts-jest": "^29.2.3",
"typescript": "5.5.4"
}
}
+1 -8
View File
@@ -65,17 +65,10 @@ export async function deploy(
// annotate resources
core.startGroup('Annotating resources')
let allPods
try {
allPods = JSON.parse((await kubectl.getAllPods()).stdout)
} catch (e) {
core.debug(`Unable to parse pods: ${e}`)
}
await annotateAndLabelResources(
deployedManifestFiles,
kubectl,
resourceTypes,
allPods
resourceTypes
)
core.endGroup()
}
+2 -19
View File
@@ -129,19 +129,13 @@ async function promoteCanary(kubectl: Kubectl, manifests: string[]) {
// annotate resources
core.startGroup('Annotating resources')
let allPods
try {
allPods = JSON.parse((await kubectl.getAllPods()).stdout)
} catch (e) {
core.debug(`Unable to parse pods: ${e}`)
}
const resources: Resource[] = getResources(
filesToAnnotate,
models.DEPLOYMENT_TYPES.concat([
models.DiscoveryAndLoadBalancerResource.SERVICE
])
)
await annotateAndLabelResources(filesToAnnotate, kubectl, resources, allPods)
await annotateAndLabelResources(filesToAnnotate, kubectl, resources)
core.endGroup()
}
@@ -219,17 +213,6 @@ async function promoteBlueGreen(kubectl: Kubectl, manifests: string[]) {
// annotate resources
core.startGroup('Annotating resources')
let allPods
try {
allPods = JSON.parse((await kubectl.getAllPods()).stdout)
} catch (e) {
core.debug(`Unable to parse pods: ${e}`)
}
await annotateAndLabelResources(
deployedManifestFiles,
kubectl,
resources,
allPods
)
await annotateAndLabelResources(deployedManifestFiles, kubectl, resources)
core.endGroup()
}
+19 -15
View File
@@ -147,8 +147,7 @@ export async function checkManifestStability(
export async function annotateAndLabelResources(
files: string[],
kubectl: Kubectl,
resourceTypes: Resource[],
allPods: any
resourceTypes: Resource[]
) {
const defaultWorkflowFileName = 'k8s-deploy-failed-workflow-annotation'
const githubToken = core.getInput('token')
@@ -163,15 +162,20 @@ export async function annotateAndLabelResources(
const deploymentConfig = await getDeploymentConfig()
const annotationKeyLabel = getWorkflowAnnotationKeyLabel()
await annotateResources(
files,
kubectl,
resourceTypes,
allPods,
annotationKeyLabel,
workflowFilePath,
deploymentConfig
).catch((err) => core.warning(`Failed to annotate resources: ${err} `))
const shouldAnnotateResources = !(
core.getInput('annotate-resources').toLowerCase() === 'false'
)
if (shouldAnnotateResources) {
await annotateResources(
files,
kubectl,
resourceTypes,
annotationKeyLabel,
workflowFilePath,
deploymentConfig
).catch((err) => core.warning(`Failed to annotate resources: ${err} `))
}
await labelResources(files, kubectl, annotationKeyLabel).catch((err) =>
core.warning(`Failed to label resources: ${err}`)
@@ -182,7 +186,6 @@ async function annotateResources(
files: string[],
kubectl: Kubectl,
resourceTypes: Resource[],
allPods: any,
annotationKey: string,
workflowFilePath: string,
deploymentConfig: DeploymentConfig
@@ -226,11 +229,13 @@ async function annotateResources(
)
)
}
for (const file of files) {
try {
const annotateResult = await kubectl.annotateFiles(
file,
annotationKeyValStr
annotationKeyValStr,
namespace
)
annotateResults.push(annotateResult)
} catch (e) {
@@ -249,8 +254,7 @@ async function annotateResources(
resource.type,
resource.name,
resource.namespace,
annotationKeyValStr,
allPods
annotationKeyValStr
)
).forEach((execResult) => annotateResults.push(execResult))
}
-11
View File
@@ -39,17 +39,6 @@ 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: ''}
+18 -4
View File
@@ -1,8 +1,12 @@
import {PrivateKubectl} from './privatekubectl'
import {
PrivateKubectl,
extractFileNames,
replaceFileNamesWithBaseNames
} from './privatekubectl'
import * as exec from '@actions/exec'
describe('Private kubectl', () => {
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 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 mockKube = new PrivateKubectl(
'kubectlPath',
'namespace',
@@ -12,8 +16,18 @@ describe('Private kubectl', () => {
)
it('should extract filenames correctly', () => {
expect(mockKube.extractFilesnames(testString)).toEqual(
'test.yml test2.yml test3.yml test4.yml test5.yml'
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`
)
})
+57 -52
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 = this.replaceFilnamesWithBasenames(kubectlCmd)
kubectlCmd = replaceFileNamesWithBaseNames(kubectlCmd)
addFileFlag = true
}
@@ -43,21 +43,21 @@ export class PrivateKubectl extends Kubectl {
]
if (addFileFlag) {
const filenames = this.extractFilesnames(kubectlCmd).split(' ')
const filenames = extractFileNames(kubectlCmd)
const tempDirectory =
process.env['runner.tempDirectory'] || os.tmpdir() + '/manifests'
eo.cwd = tempDirectory
privateClusterArgs.push(...['--file', '.'])
let filenamesArr = filenames[0].split(',')
for (let index = 0; index < filenamesArr.length; index++) {
const file = filenamesArr[index]
if (!file) {
continue
for (const filename of filenames) {
try {
this.moveFileToTempManifestDir(filename)
} catch (e) {
core.debug(
`Error moving file ${filename} to temp directory: ${e}`
)
}
this.moveFileToTempManifestDir(file)
}
}
@@ -95,49 +95,6 @@ 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 ')
}
@@ -181,3 +138,51 @@ 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
}
+5 -1
View File
@@ -23,7 +23,11 @@ export async function getDeploymentConfig(): Promise<DeploymentConfig> {
)
}
const imageNames = core.getInput('images').split('\n') || []
const imageNames =
core
.getInput('images')
.split('\n')
.filter((image) => image.length > 0) || []
const imageDockerfilePathMap: {[id: string]: string} = {}
const pullImages = !(core.getInput('pull-images').toLowerCase() === 'false')
+9 -2
View File
@@ -61,8 +61,7 @@ export async function annotateChildPods(
resourceType: string,
resourceName: string,
namespace: string | undefined,
annotationKeyValStr: string,
allPods
annotationKeyValStr: string
): Promise<ExecOutput[]> {
let owner = resourceName
if (resourceType.toLowerCase().indexOf('deployment') > -1) {
@@ -70,6 +69,14 @@ export async function annotateChildPods(
}
const commandExecutionResults = []
let allPods
try {
allPods = JSON.parse((await kubectl.getAllPods()).stdout)
} catch (e) {
core.debug(`Unable to parse pods: ${e}`)
}
if (allPods?.items && allPods.items?.length > 0) {
allPods.items.forEach((pod) => {
const owners = pod?.metadata?.ownerReferences
+2 -2
View File
@@ -7,7 +7,7 @@ def delete(kind, name, namespace):
if (name == "all"):
print('kubectl delete --all' + kind + ' -n ' + namespace)
deletion = subprocess.Popen(
['kubectl', 'delete', kind, name, '--namespace', namespace])
['kubectl', 'delete', kind, '--all', '--namespace', namespace])
result, err = deletion.communicate()
else:
print('kubectl delete ' + kind + ' ' + name + ' -n ' + namespace)
@@ -21,7 +21,7 @@ def delete(kind, name, namespace):
def main():
kind = sys.argv[1]
name = sys.argv[2]
namespace = 'test-' + sys.argv[3]
namespace = sys.argv[3]
delete(kind, name, namespace)
+21 -15
View File
@@ -41,10 +41,6 @@ def parseArgs(sysArgs):
argsDict[labelsKey] = stringListToDict(
argsDict[labelsKey].split(","), ":")
if annotationsKey in argsDict:
argsDict[annotationsKey] = stringListToDict(
argsDict[annotationsKey].split(","), ":")
if selectorLabelsKey in argsDict:
argsDict[selectorLabelsKey] = stringListToDict(
argsDict[selectorLabelsKey].split(","), ":")
@@ -60,6 +56,9 @@ def parseArgs(sysArgs):
if ingressServicesKey in argsDict:
argsDict[ingressServicesKey] = argsDict[ingressServicesKey].split(",")
if annotationsKey in argsDict:
argsDict[annotationsKey] = argsDict[annotationsKey].split(",")
return argsDict
@@ -98,14 +97,14 @@ def verifyDeployment(deployment, parsedArgs):
return dictMatch, msg
if annotationsKey in parsedArgs:
dictMatch, msg = compareDicts(
deployment['metadata']['annotations'], parsedArgs[annotationsKey], annotationsKey)
if not dictMatch:
return dictMatch, msg
if len(parsedArgs[annotationsKey]) != len(deployment['metadata']['annotations']):
return False, f"expected {len(parsedArgs[annotationsKey])} annotations but found {len(deployment['metadata']['annotations'])}"
keysPresent, msg = validateKeyPresence(
deployment['metadata']['annotations'], parsedArgs[annotationsKey])
if not keysPresent:
return keysPresent, msg
return True, ""
def verifyService(service, parsedArgs):
# test selector labels, labels, annotations
if not selectorLabelsKey in parsedArgs:
@@ -124,10 +123,10 @@ def verifyService(service, parsedArgs):
return dictMatch, msg
if annotationsKey in parsedArgs:
dictMatch, msg = compareDicts(
service['metadata']['annotations'], parsedArgs[annotationsKey], annotationsKey)
if not dictMatch:
return dictMatch, msg
keysPresent, msg = validateKeyPresence(
service['metadata']['annotations'], parsedArgs[annotationsKey])
if not keysPresent:
return keysPresent, msg
return True, ""
@@ -188,6 +187,13 @@ def compareDicts(actual: dict, expected: dict, paramName=""):
return True, ""
def validateKeyPresence(actualDict: dict, expectedKeys: list):
actualKeys = actualDict.keys()
for key in expectedKeys:
if key not in actualKeys:
return False, f"expected key {key} not found in actual dict. \n actual dict keys {','.join(actualKeys)}"
return True, ""
def main():
parsedArgs: dict = parseArgs(sys.argv[1:])
@@ -220,7 +226,7 @@ def main():
if k8_object == None:
raise ValueError(f"{kind} {name} was not found")
except:
msg = kind+' '+name+' not created or not found'
getAllObjectsCmd = azPrefix + 'kubectl get '+kind+' -n '+namespace
+33
View File
@@ -0,0 +1,33 @@
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