Compare commits

..

31 Commits

Author SHA1 Message Date
GitHub Action 97a78b4bf0 build 2024-12-09 22:15:39 +00:00
David Gamero 3d107b044d v5.0.1 Release with Fleet Types (#358)
* extract resource type

* fleet details

* new release with fleet

* format

* type params

* format

* promote input

* format

* fleet type

* format pls
2024-12-09 17:14:44 -05:00
Audra Stump d1acc1a47b enable fleet cluster deployment (#356)
* added fleet exception to rollout cmd

* removed fleet check for rollout

* modified casing

* modified approach for fleet check

* tidying up

* defaulting to Microsoft.ContainerService/managedClusters

* ran prettier command

* modified manifest stablity check

* ran prettier check

* moved lowercase check to beginning

---------

Co-authored-by: audrastump <stumpaudra@microsoft.com>
2024-12-06 14:32:48 -05:00
dependabot[bot] bf768b3109 Bump the actions group across 1 directory with 7 updates (#346)
* Bump the actions group across 1 directory with 7 updates

Bumps the actions group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) | `1.10.1` | `1.11.1` |
| [@octokit/core](https://github.com/octokit/core.js) | `3.6.0` | `6.1.2` |
| [@octokit/plugin-retry](https://github.com/octokit/plugin-retry.js) | `3.0.9` | `7.1.2` |
| [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) | `29.5.13` | `29.5.14` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.7.4` | `22.8.7` |
| [prettier](https://github.com/prettier/prettier) | `2.8.8` | `3.3.3` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.6.2` | `5.6.3` |



Updates `@actions/core` from 1.10.1 to 1.11.1
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

Updates `@octokit/core` from 3.6.0 to 6.1.2
- [Release notes](https://github.com/octokit/core.js/releases)
- [Commits](https://github.com/octokit/core.js/compare/v3.6.0...v6.1.2)

Updates `@octokit/plugin-retry` from 3.0.9 to 7.1.2
- [Release notes](https://github.com/octokit/plugin-retry.js/releases)
- [Commits](https://github.com/octokit/plugin-retry.js/compare/v3.0.9...v7.1.2)

Updates `@types/jest` from 29.5.13 to 29.5.14
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

Updates `@types/node` from 22.7.4 to 22.8.7
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `prettier` from 2.8.8 to 3.3.3
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.8.8...3.3.3)

Updates `typescript` from 5.6.2 to 5.6.3
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.6.2...v5.6.3)

---
updated-dependencies:
- dependency-name: "@actions/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: "@octokit/core"
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: "@octokit/plugin-retry"
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: "@types/jest"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: actions
...

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

* fixed octokit imports

* fix fs imports

* prettier

* babel config

* format

* format action update

---------

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>
2024-11-07 09:18:35 -05:00
dependabot[bot] d3b3950a9c Bump github/codeql-action in /.github/workflows in the actions group (#344)
Bumps the actions group in /.github/workflows with 1 update: [github/codeql-action](https://github.com/github/codeql-action).


Updates `github/codeql-action` from 3.26.13 to 3.27.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/f779452ac5af1c261dce0346a8f964149f49322b...662472033e021d55d94146f66f6058822b0b39fd)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-06 12:07:46 -08:00
dependabot[bot] 4b49af4189 Bump github/codeql-action in /.github/workflows in the actions group (#342) 2024-10-23 12:15:33 -07:00
dependabot[bot] 0c838316d4 Bump the actions group across 1 directory with 2 updates (#339)
Bumps the actions group with 2 updates in the /.github/workflows directory: [github/codeql-action](https://github.com/github/codeql-action) and [azure/login](https://github.com/azure/login).


Updates `github/codeql-action` from 3.26.6 to 3.26.12
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/4dd16135b69a43b6c8efb853346f8437d92d3c93...c36620d31ac7c881962c3d9dd939c40ec9434f2b)

Updates `azure/login` from 2.1.1 to 2.2.0
- [Release notes](https://github.com/azure/login/releases)
- [Commits](https://github.com/azure/login/compare/v2.1.1...v2.2.0)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: azure/login
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-08 17:12:54 -04:00
dependabot[bot] e5725dfe9f Bump the actions group across 1 directory with 14 updates (#338)
* Bump the actions group across 1 directory with 14 updates

Bumps the actions group with 14 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) | `1.10.0` | `1.10.1` |
| [@actions/io](https://github.com/actions/toolkit/tree/HEAD/packages/io) | `1.1.2` | `1.1.3` |
| [@actions/tool-cache](https://github.com/actions/toolkit/tree/HEAD/packages/tool-cache) | `1.1.2` | `2.0.1` |
| [@octokit/core](https://github.com/octokit/core.js) | `3.6.0` | `6.1.2` |
| [@octokit/plugin-retry](https://github.com/octokit/plugin-retry.js) | `3.0.9` | `7.1.2` |
| [@types/minipass](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/minipass) | `3.1.2` | `3.3.5` |
| [js-yaml](https://github.com/nodeca/js-yaml) | `3.13.1` | `4.1.0` |
| [@types/js-yaml](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/js-yaml) | `3.12.7` | `4.0.9` |
| [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) | `26.0.24` | `29.5.13` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `12.20.55` | `22.7.4` |
| [@vercel/ncc](https://github.com/vercel/ncc) | `0.36.1` | `0.38.2` |
| [prettier](https://github.com/prettier/prettier) | `2.8.8` | `3.3.3` |
| [ts-jest](https://github.com/kulshekhar/ts-jest) | `29.2.3` | `29.2.5` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.5.4` | `5.6.2` |



Updates `@actions/core` from 1.10.0 to 1.10.1
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

Updates `@actions/io` from 1.1.2 to 1.1.3
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/io/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/io)

Updates `@actions/tool-cache` from 1.1.2 to 2.0.1
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/tool-cache/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/@actions/artifact@2.0.1/packages/tool-cache)

Updates `@octokit/core` from 3.6.0 to 6.1.2
- [Release notes](https://github.com/octokit/core.js/releases)
- [Commits](https://github.com/octokit/core.js/compare/v3.6.0...v6.1.2)

Updates `@octokit/plugin-retry` from 3.0.9 to 7.1.2
- [Release notes](https://github.com/octokit/plugin-retry.js/releases)
- [Commits](https://github.com/octokit/plugin-retry.js/compare/v3.0.9...v7.1.2)

Updates `@types/minipass` from 3.1.2 to 3.3.5
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/minipass)

Updates `js-yaml` from 3.13.1 to 4.1.0
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.13.1...4.1.0)

Updates `@types/js-yaml` from 3.12.7 to 4.0.9
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/js-yaml)

Updates `@types/jest` from 26.0.24 to 29.5.13
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

Updates `@types/js-yaml` from 3.12.7 to 4.0.9
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/js-yaml)

Updates `@types/node` from 12.20.55 to 22.7.4
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@vercel/ncc` from 0.36.1 to 0.38.2
- [Release notes](https://github.com/vercel/ncc/releases)
- [Commits](https://github.com/vercel/ncc/compare/0.36.1...0.38.2)

Updates `prettier` from 2.8.8 to 3.3.3
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.8.8...3.3.3)

Updates `ts-jest` from 29.2.3 to 29.2.5
- [Release notes](https://github.com/kulshekhar/ts-jest/releases)
- [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.2.3...v29.2.5)

Updates `typescript` from 5.5.4 to 5.6.2
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.5.4...v5.6.2)

---
updated-dependencies:
- dependency-name: "@actions/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: "@actions/io"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: "@actions/tool-cache"
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: "@octokit/core"
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: "@octokit/plugin-retry"
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: "@types/minipass"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: js-yaml
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: "@types/js-yaml"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: "@types/jest"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: "@types/js-yaml"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: "@vercel/ncc"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: ts-jest
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: actions
...

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

* code changes to use yaml.loadAll and upgrade of octokit version

* few code changes to handle errors

* apply prettier formatting

* downgrade prettier version since actionsx/prettier@v3 doesn't support the latest version

* adding try catch to handle yaml loading

* addressing comments

* updating assertions for name

* apply prettier code

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Vidya Reddy <59590642+Vidya2606@users.noreply.github.com>
2024-10-03 17:08:48 -04:00
dependabot[bot] b34f3e7f18 Bump the actions group in /.github/workflows with 7 updates (#330)
Bumps the actions group in /.github/workflows with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `2` | `4` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.24.8` | `3.26.6` |
| [actions/stale](https://github.com/actions/stale) | `3` | `9` |
| [actionsx/prettier](https://github.com/actionsx/prettier) | `2` | `3` |
| [Azure/setup-kubectl](https://github.com/azure/setup-kubectl) | `3` | `4` |
| [actions/setup-python](https://github.com/actions/setup-python) | `2` | `5` |
| [azure/login](https://github.com/azure/login) | `1.4.3` | `2.1.1` |


Updates `actions/checkout` from 2 to 4
- [Release notes](https://github.com/actions/checkout/releases)
- [Commits](https://github.com/actions/checkout/compare/v2...v4)

Updates `github/codeql-action` from 3.24.8 to 3.26.6
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/05963f47d870e2cb19a537396c1f668a348c7d8f...4dd16135b69a43b6c8efb853346f8437d92d3c93)

Updates `actions/stale` from 3 to 9
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v3...v9)

Updates `actionsx/prettier` from 2 to 3
- [Release notes](https://github.com/actionsx/prettier/releases)
- [Commits](https://github.com/actionsx/prettier/compare/v2...v3)

Updates `Azure/setup-kubectl` from 3 to 4
- [Release notes](https://github.com/azure/setup-kubectl/releases)
- [Changelog](https://github.com/Azure/setup-kubectl/blob/main/CHANGELOG.md)
- [Commits](https://github.com/azure/setup-kubectl/compare/v3...v4)

Updates `actions/setup-python` from 2 to 5
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v2...v5)

Updates `azure/login` from 1.4.3 to 2.1.1
- [Release notes](https://github.com/azure/login/releases)
- [Commits](https://github.com/azure/login/compare/v1.4.3...v2.1.1)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: actionsx/prettier
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: Azure/setup-kubectl
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: azure/login
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-11 15:30:21 -04:00
Brandon Foley 10d196d204 Add dependabot (#329) 2024-09-06 11:15:27 -04:00
Jaiveer Katariya df58fb461e Supporting Multiple Files With the Same Name (#327)
* 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

* refactored getting tmp filename to use entire path, and refactored private to use filepath relative to tmp dir

* wip

* merging master

* this should fail

* added UTs

* restructured plus UTs plus debug logs

* resolved dir not existing and UTs

* cleanup

* no silent failure

* Reverting private logic

* this might work

* root level files for temp... bizarre issue

* need to actually write contents

* no more cwdir

* moving everything out of temp

* deleting unused function

* supporting windows filepaths for private cluster shallow path generation

---------

Co-authored-by: David Gamero <david340804@gmail.com>
2024-08-07 10:48:18 -04:00
David Gamero a999ffcd6c upgrade to typescript 5 (#326) 2024-07-26 09:29:18 -04: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
50 changed files with 10503 additions and 18935 deletions
+18
View File
@@ -0,0 +1,18 @@
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
groups:
actions:
patterns:
- '*'
- package-ecosystem: github-actions
directory: .github/workflows
schedule:
interval: weekly
groups:
actions:
patterns:
- '*'
+7 -4
View File
@@ -10,10 +10,13 @@ jobs:
CodeQL-Build: CodeQL-Build:
# CodeQL runs on ubuntu-latest and windows-latest # CodeQL runs on ubuntu-latest and windows-latest
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3 uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7
with: with:
# We must fetch at least the immediate parents so that if this is # We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head. # a pull request then we can checkout the head.
@@ -21,7 +24,7 @@ jobs:
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@662472033e021d55d94146f66f6058822b0b39fd #v3.27.0
# Override language selection by uncommenting this and choosing your languages # Override language selection by uncommenting this and choosing your languages
# with: # with:
# languages: go, javascript, csharp, python, cpp, java # languages: go, javascript, csharp, python, cpp, java
@@ -29,7 +32,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # 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) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v2 uses: github/codeql-action/autobuild@662472033e021d55d94146f66f6058822b0b39fd #v3.27.0
# ️ Command-line programs to run using the OS shell. # ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl # 📚 https://git.io/JvXDl
@@ -43,4 +46,4 @@ jobs:
# make release # make release
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2 uses: github/codeql-action/analyze@662472033e021d55d94146f66f6058822b0b39fd #v3.27.0
+2 -2
View File
@@ -13,7 +13,7 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job # Steps represent a sequence of tasks that will be executed as part of the job
steps: steps:
- uses: actions/stale@v3 - uses: actions/stale@v9
name: Setting issue as idle name: Setting issue as idle
with: with:
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
@@ -24,7 +24,7 @@ jobs:
operations-per-run: 100 operations-per-run: 100
exempt-issue-labels: 'backlog' exempt-issue-labels: 'backlog'
- uses: actions/stale@v3 - uses: actions/stale@v9
name: Setting PR as idle name: Setting PR as idle
with: with:
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
+4 -4
View File
@@ -10,9 +10,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: install deps
run: npm install
- name: Enforce Prettier - name: Enforce Prettier
uses: actionsx/prettier@v2 run: npm run format-check
with:
args: --check .
+12 -8
View File
@@ -1,14 +1,18 @@
name: Create release PR name: Release Project
on: on:
push:
branches:
- main
paths:
- CHANGELOG.md
workflow_dispatch: workflow_dispatch:
inputs:
release:
description: 'Define release version (ex: v1, v2, v3)'
required: true
jobs: jobs:
release-pr: release:
uses: OliverMKing/javascript-release-workflow/.github/workflows/release-pr.yml@main permissions:
actions: read
contents: write
uses: Azure/action-release-workflows/.github/workflows/release_js_project.yaml@v1
with: with:
release: ${{ github.event.inputs.release }} changelogPath: ./CHANGELOG.md
@@ -18,7 +18,7 @@ jobs:
KUBECONFIG: /home/runner/.kube/config KUBECONFIG: /home/runner/.kube/config
NAMESPACE: test-${{ github.run_id }} NAMESPACE: test-${{ github.run_id }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Install dependencies - name: Install dependencies
run: | run: |
@@ -31,7 +31,7 @@ jobs:
- name: Build - name: Build
run: ncc build src/run.ts -o lib run: ncc build src/run.ts -o lib
- uses: Azure/setup-kubectl@v3 - uses: Azure/setup-kubectl@v4
name: Install Kubectl name: Install Kubectl
- id: setup-minikube - id: setup-minikube
@@ -46,7 +46,7 @@ jobs:
- name: Create namespace to run tests - name: Create namespace to run tests
run: kubectl create ns ${{ env.NAMESPACE }} run: kubectl create ns ${{ env.NAMESPACE }}
- uses: actions/setup-python@v2 - uses: actions/setup-python@v5
name: Install Python name: Install Python
with: with:
python-version: '3.x' python-version: '3.x'
@@ -64,9 +64,13 @@ jobs:
images: nginx:1.14.2 images: nginx:1.14.2
manifests: | manifests: |
test/integration/manifests/test.yml test/integration/manifests/test.yml
test/integration/manifests/manifest_test_dir/test.yml
action: deploy action: deploy
- name: Checking if deployments and services were created - name: Checking if deployments and services were created
run: | 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_-_basic selectorLabels=app:nginx 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_-_basic selectorLabels=app:nginx
python test/integration/k8s-deploy-test.py namespace=${{ env.NAMESPACE }} kind=Service name=nginx-service labels=workflow:actions.github.com-k8s-deploy,workflowFriendlyName:Minikube_Integration_Tests_-_basic selectorLabels=app:nginx python test/integration/k8s-deploy-test.py namespace=${{ env.NAMESPACE }} kind=Service name=nginx-service labels=workflow:actions.github.com-k8s-deploy,workflowFriendlyName:Minikube_Integration_Tests_-_basic selectorLabels=app:nginx
python test/integration/k8s-deploy-test.py namespace=${{ env.NAMESPACE }} kind=Deployment name=nginx-deployment3 containerName=nginx:1.14.2 labels=app:nginx3,workflow:actions.github.com-k8s-deploy,workflowFriendlyName:Minikube_Integration_Tests_-_basic selectorLabels=app:nginx3
python test/integration/k8s-deploy-test.py namespace=${{ env.NAMESPACE }} kind=Service name=nginx-service3 labels=workflow:actions.github.com-k8s-deploy,workflowFriendlyName:Minikube_Integration_Tests_-_basic selectorLabels=app:nginx3
@@ -18,7 +18,7 @@ jobs:
KUBECONFIG: /home/runner/.kube/config KUBECONFIG: /home/runner/.kube/config
NAMESPACE: test-${{ github.run_id }} NAMESPACE: test-${{ github.run_id }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Install dependencies - name: Install dependencies
run: | run: |
@@ -31,14 +31,14 @@ jobs:
- name: Build - name: Build
run: ncc build src/run.ts -o lib run: ncc build src/run.ts -o lib
- uses: Azure/setup-kubectl@v3 - uses: Azure/setup-kubectl@v4
name: Install Kubectl name: Install Kubectl
- id: setup-minikube - id: setup-minikube
name: Setup Minikube name: Setup Minikube
uses: medyagh/setup-minikube@latest uses: medyagh/setup-minikube@latest
with: with:
minikube-version: 1.24.0 minikube-version: 1.31.2
kubernetes-version: 1.22.3 kubernetes-version: 1.22.3
driver: 'none' driver: 'none'
timeout-minutes: 3 timeout-minutes: 3
@@ -46,7 +46,7 @@ jobs:
- name: Create namespace to run tests - name: Create namespace to run tests
run: kubectl create ns ${{ env.NAMESPACE }} run: kubectl create ns ${{ env.NAMESPACE }}
- uses: actions/setup-python@v2 - uses: actions/setup-python@v5
name: Install Python name: Install Python
with: with:
python-version: '3.x' python-version: '3.x'
@@ -18,7 +18,7 @@ jobs:
KUBECONFIG: /home/runner/.kube/config KUBECONFIG: /home/runner/.kube/config
NAMESPACE: test-${{ github.run_id }} NAMESPACE: test-${{ github.run_id }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Install dependencies - name: Install dependencies
run: | run: |
@@ -31,14 +31,14 @@ jobs:
- name: Build - name: Build
run: ncc build src/run.ts -o lib run: ncc build src/run.ts -o lib
- uses: Azure/setup-kubectl@v3 - uses: Azure/setup-kubectl@v4
name: Install Kubectl name: Install Kubectl
- id: setup-minikube - id: setup-minikube
name: Setup Minikube name: Setup Minikube
uses: medyagh/setup-minikube@latest uses: medyagh/setup-minikube@latest
with: with:
minikube-version: 1.24.0 minikube-version: 1.31.2
kubernetes-version: 1.22.3 kubernetes-version: 1.22.3
driver: 'none' driver: 'none'
timeout-minutes: 3 timeout-minutes: 3
@@ -46,7 +46,7 @@ jobs:
- name: Create namespace to run tests - name: Create namespace to run tests
run: kubectl create ns ${{ env.NAMESPACE }} run: kubectl create ns ${{ env.NAMESPACE }}
- uses: actions/setup-python@v2 - uses: actions/setup-python@v5
name: Install Python name: Install Python
with: with:
python-version: '3.x' python-version: '3.x'
@@ -18,7 +18,7 @@ jobs:
KUBECONFIG: /home/runner/.kube/config KUBECONFIG: /home/runner/.kube/config
NAMESPACE: test-${{ github.run_id }} NAMESPACE: test-${{ github.run_id }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Install dependencies - name: Install dependencies
run: | run: |
@@ -31,7 +31,7 @@ jobs:
- name: Build - name: Build
run: ncc build src/run.ts -o lib run: ncc build src/run.ts -o lib
- uses: Azure/setup-kubectl@v3 - uses: Azure/setup-kubectl@v4
name: Install Kubectl name: Install Kubectl
- id: setup-minikube - id: setup-minikube
@@ -56,7 +56,7 @@ jobs:
- name: Create namespace to run tests - name: Create namespace to run tests
run: kubectl create ns ${{ env.NAMESPACE }} run: kubectl create ns ${{ env.NAMESPACE }}
- uses: actions/setup-python@v2 - uses: actions/setup-python@v5
name: Install Python name: Install Python
with: with:
python-version: '3.x' python-version: '3.x'
@@ -18,7 +18,7 @@ jobs:
KUBECONFIG: /home/runner/.kube/config KUBECONFIG: /home/runner/.kube/config
NAMESPACE: test-${{ github.run_id }} NAMESPACE: test-${{ github.run_id }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Install dependencies - name: Install dependencies
run: | run: |
@@ -31,7 +31,7 @@ jobs:
- name: Build - name: Build
run: ncc build src/run.ts -o lib run: ncc build src/run.ts -o lib
- uses: Azure/setup-kubectl@v3 - uses: Azure/setup-kubectl@v4
name: Install Kubectl name: Install Kubectl
- id: setup-minikube - id: setup-minikube
@@ -46,7 +46,7 @@ jobs:
- name: Create namespace to run tests - name: Create namespace to run tests
run: kubectl create ns ${{ env.NAMESPACE }} run: kubectl create ns ${{ env.NAMESPACE }}
- uses: actions/setup-python@v2 - uses: actions/setup-python@v5
name: Install Python name: Install Python
with: with:
python-version: '3.x' python-version: '3.x'
@@ -13,12 +13,12 @@ on:
jobs: jobs:
run-integration-test: run-integration-test:
name: Run Minikube Integration Tests name: Run Minikube Integration Tests
runs-on: ubuntu-20.04 runs-on: ubuntu-latest
env: env:
KUBECONFIG: /home/runner/.kube/config KUBECONFIG: /home/runner/.kube/config
NAMESPACE: test-${{ github.run_id }} NAMESPACE: test-${{ github.run_id }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Install dependencies - name: Install dependencies
run: | run: |
@@ -31,7 +31,7 @@ jobs:
- name: Build - name: Build
run: ncc build src/run.ts -o lib run: ncc build src/run.ts -o lib
- uses: Azure/setup-kubectl@v3 - uses: Azure/setup-kubectl@v4
name: Install Kubectl name: Install Kubectl
- id: setup-minikube - id: setup-minikube
@@ -56,7 +56,7 @@ jobs:
- name: Create namespace to run tests - name: Create namespace to run tests
run: kubectl create ns ${{ env.NAMESPACE }} run: kubectl create ns ${{ env.NAMESPACE }}
- uses: actions/setup-python@v2 - uses: actions/setup-python@v5
name: Install Python name: Install Python
with: with:
python-version: '3.x' python-version: '3.x'
@@ -19,7 +19,7 @@ jobs:
contents: read contents: read
id-token: write id-token: write
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Install dependencies - name: Install dependencies
run: | run: |
@@ -30,20 +30,20 @@ jobs:
- name: Build - name: Build
run: ncc build src/run.ts -o lib run: ncc build src/run.ts -o lib
- name: Azure login - name: Azure login
uses: azure/login@v1.4.3 uses: azure/login@v2.2.0
with: with:
client-id: ${{ secrets.AZURE_CLIENT_ID }} client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- uses: Azure/setup-kubectl@v3 - uses: Azure/setup-kubectl@v4
name: Install Kubectl name: Install Kubectl
- name: Create private AKS cluster and set context - name: Create private AKS cluster and set context
run: | run: |
set +x set +x
# create cluster # 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 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 }} az aks get-credentials --resource-group ${{ env.NAMESPACE }} --name ${{ env.NAMESPACE }}
@@ -51,7 +51,7 @@ jobs:
run: | run: |
az aks command invoke --resource-group ${{ env.NAMESPACE }} --name ${{ env.NAMESPACE }} --command "kubectl create ns ${{ env.NAMESPACE }}" az aks command invoke --resource-group ${{ env.NAMESPACE }} --name ${{ env.NAMESPACE }} --command "kubectl create ns ${{ env.NAMESPACE }}"
- uses: actions/setup-python@v2 - uses: actions/setup-python@v5
name: Install Python name: Install Python
with: with:
python-version: '3.x' python-version: '3.x'
@@ -63,6 +63,7 @@ jobs:
images: nginx:1.14.2 images: nginx:1.14.2
manifests: | manifests: |
test/integration/manifests/test.yml test/integration/manifests/test.yml
test/integration/manifests/test2.yml
action: deploy action: deploy
private-cluster: true private-cluster: true
resource-group: ${{ env.NAMESPACE }} 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=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=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 - name: Clean up AKS cluster
if: ${{ always() }} if: ${{ always() }}
run: | 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@v4
- 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@v4
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@v5
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 -1
View File
@@ -14,7 +14,7 @@ jobs:
name: Run Unit Tests name: Run Unit Tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- run: | - run: |
npm install npm install
npm test npm test
+34
View File
@@ -0,0 +1,34 @@
# Changelog
## [5.0.1] - 2024-03-12
### Added
- #356 Add fleet support
## [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
+32 -24
View File
@@ -113,14 +113,22 @@ Following are the key capabilities of this action:
<td>force </br></br>(Optional)</td> <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> <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>
<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> <tr>
<td>annotate-namespace</br></br>(Optional)</td> <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>
<tr> <tr>
<td>skip-tls-verify</br></br>(Optional)</td> <td>skip-tls-verify</br></br>(Optional)</td>
<td>Acceptable values: true/false</br>Default value: false</br>True if the insecure-skip-tls-verify option should be used</td> <td>Acceptable values: true/false</br>Default value: false</br>True if the insecure-skip-tls-verify option should be used</td>
</tr> </tr>
<tr>
<td>resource-type (Optional)</td>
<td>Acceptable values: `Microsoft.ContainerService/managedClusters` (default), 'Microsoft.ContainerService/fleets'</td>
</tr>
</table> </table>
## Usage Examples ## Usage Examples
@@ -128,7 +136,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@v4 - uses: Azure/k8s-deploy@v5
with: with:
namespace: 'myapp' namespace: 'myapp'
manifests: | manifests: |
@@ -142,7 +150,7 @@ Following are the key capabilities of this action:
### Private cluster deployment ### Private cluster deployment
```yaml ```yaml
- uses: Azure/k8s-deploy@v4 - uses: Azure/k8s-deploy@v5
with: with:
resource-group: yourResourceGroup resource-group: yourResourceGroup
name: yourClusterName name: yourClusterName
@@ -162,7 +170,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@v4 - uses: Azure/k8s-deploy@v5
with: with:
namespace: 'myapp' namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}' images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
@@ -181,7 +189,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@v4 - uses: Azure/k8s-deploy@v5
with: with:
namespace: 'myapp' namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}' images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
@@ -199,7 +207,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@v4 - uses: Azure/k8s-deploy@v5
with: with:
namespace: 'myapp' namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}' images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
@@ -220,7 +228,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@v4 - uses: Azure/k8s-deploy@v5
with: with:
namespace: 'myapp' namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }} ' images: 'contoso.azurecr.io/myapp:${{ event.run_id }} '
@@ -239,7 +247,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@v4 - uses: Azure/k8s-deploy@v5
with: with:
namespace: 'myapp' namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}' images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
@@ -259,7 +267,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@v4 - uses: Azure/k8s-deploy@v5
with: with:
namespace: 'myapp' namespace: 'myapp'
images: 'contoso.azurecr.io/myapp:${{ event.run_id }}' images: 'contoso.azurecr.io/myapp:${{ event.run_id }}'
@@ -288,7 +296,7 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@master - uses: actions/checkout@v4
- uses: Azure/docker-login@v1 - uses: Azure/docker-login@v1
with: with:
@@ -300,23 +308,23 @@ jobs:
docker build . -t contoso.azurecr.io/k8sdemo:${{ github.sha }} docker build . -t contoso.azurecr.io/k8sdemo:${{ github.sha }}
docker push 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. # Set the target AKS cluster.
- uses: Azure/aks-set-context@v1 - uses: Azure/aks-set-context@v4
with: with:
creds: '${{ secrets.AZURE_CREDENTIALS }}' creds: '${{ secrets.AZURE_CREDENTIALS }}'
cluster-name: contoso cluster-name: contoso
resource-group: contoso-rg resource-group: contoso-rg
- uses: Azure/k8s-create-secret@v1.1 - uses: Azure/k8s-create-secret@v4
with: with:
container-registry-url: contoso.azurecr.io container-registry-url: contoso.azurecr.io
container-registry-username: ${{ secrets.REGISTRY_USERNAME }} container-registry-username: ${{ secrets.REGISTRY_USERNAME }}
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@v4 - uses: Azure/k8s-deploy@v5
with: with:
action: deploy action: deploy
manifests: | manifests: |
@@ -337,7 +345,7 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@master - uses: actions/checkout@v4
- uses: Azure/docker-login@v1 - uses: Azure/docker-login@v1
with: with:
@@ -349,13 +357,13 @@ jobs:
docker build . -t contoso.azurecr.io/k8sdemo:${{ github.sha }} docker build . -t contoso.azurecr.io/k8sdemo:${{ github.sha }}
docker push 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: with:
kubeconfig: ${{ secrets.KUBE_CONFIG }} kubeconfig: ${{ secrets.KUBE_CONFIG }}
- uses: Azure/k8s-create-secret@v1.1 - uses: Azure/k8s-create-secret@v4
with: with:
container-registry-url: contoso.azurecr.io container-registry-url: contoso.azurecr.io
container-registry-username: ${{ secrets.REGISTRY_USERNAME }} container-registry-username: ${{ secrets.REGISTRY_USERNAME }}
@@ -387,7 +395,7 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@master - uses: actions/checkout@v4
- uses: Azure/docker-login@v1 - uses: Azure/docker-login@v1
with: with:
@@ -419,16 +427,16 @@ jobs:
username: ${{ secrets.REGISTRY_USERNAME }} username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }} password: ${{ secrets.REGISTRY_PASSWORD }}
- uses: azure/setup-kubectl@v2.0 - uses: azure/setup-kubectl@v4
# Set the target AKS cluster. # Set the target AKS cluster.
- uses: Azure/aks-set-context@v1 - uses: Azure/aks-set-context@v4
with: with:
creds: '${{ secrets.AZURE_CREDENTIALS }}' creds: '${{ secrets.AZURE_CREDENTIALS }}'
cluster-name: contoso cluster-name: contoso
resource-group: contoso-rg resource-group: contoso-rg
- uses: Azure/k8s-create-secret@v1.1 - uses: Azure/k8s-create-secret@v4
with: with:
namespace: ${{ env.NAMESPACE }} namespace: ${{ env.NAMESPACE }}
container-registry-url: contoso.azurecr.io container-registry-url: contoso.azurecr.io
@@ -436,7 +444,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-bake@v2 - uses: azure/k8s-bake@v3
with: with:
renderEngine: 'helm' renderEngine: 'helm'
helmChart: './aks-helloworld/' helmChart: './aks-helloworld/'
@@ -446,7 +454,7 @@ jobs:
helm-version: 'latest' helm-version: 'latest'
id: bake id: bake
- uses: Azure/k8s-deploy@v1.2 - uses: Azure/k8s-deploy@v5
with: with:
action: deploy action: deploy
manifests: ${{ steps.bake.outputs.manifestsBundle }} manifests: ${{ steps.bake.outputs.manifestsBundle }}
+6 -2
View File
@@ -59,8 +59,12 @@ inputs:
description: 'Github token' description: 'Github token'
default: ${{ github.token }} default: ${{ github.token }}
required: true required: true
annotate-resources:
description: 'Annotate the resources. If set to false all annotations are skipped completely.'
required: false
default: true
annotate-namespace: annotate-namespace:
description: 'Annotate the target namespace' description: 'Annotate the target namespace. Ignored when annotate-resources is set to false.'
required: false required: false
default: true default: true
private-cluster: private-cluster:
@@ -80,5 +84,5 @@ inputs:
branding: branding:
color: 'green' color: 'green'
runs: runs:
using: 'node16' using: 'node20'
main: 'lib/index.js' main: 'lib/index.js'
+6
View File
@@ -0,0 +1,6 @@
module.exports = {
presets: [
['@babel/preset-env', {targets: {node: 'current'}}],
'@babel/preset-typescript'
]
}
+11 -2
View File
@@ -1,11 +1,20 @@
module.exports = { module.exports = {
clearMocks: true,
moduleFileExtensions: ['js', 'ts'], moduleFileExtensions: ['js', 'ts'],
testEnvironment: 'node', testEnvironment: 'node',
testMatch: ['**/*.test.ts'], testMatch: ['**/*.test.ts'],
transform: { transform: {
'^.+\\.ts$': 'ts-jest' '\\.[jt]sx?$': 'babel-jest'
}, },
transformIgnorePatterns: [
'node_modules/(?!' +
[
'@octokit',
'universal-user-agent',
'before-after-hook',
'minimist'
].join('|') +
')'
],
verbose: true, verbose: true,
testTimeout: 9000 testTimeout: 9000
} }
+4216 -10666
View File
File diff suppressed because one or more lines are too long
+4915 -7382
View File
File diff suppressed because it is too large Load Diff
+22 -17
View File
@@ -1,33 +1,38 @@
{ {
"name": "k8s-deploy-action", "name": "k8s-deploy-action",
"version": "0.0.0", "version": "5.0.0",
"author": "Deepak Sattiraju", "author": "Deepak Sattiraju",
"license": "MIT", "license": "MIT",
"scripts": { "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", "test": "jest",
"coverage": "jest --coverage=true", "coverage": "jest --coverage=true",
"format": "prettier --write .", "format": "prettier --write .",
"format-check": "prettier --check ." "format-check": "prettier --check ."
}, },
"dependencies": { "dependencies": {
"@actions/core": "^1.10.0", "@actions/core": "^1.11.1",
"@actions/exec": "^1.0.0", "@actions/exec": "^1.0.0",
"@actions/io": "^1.0.0", "@actions/io": "^1.1.3",
"@actions/tool-cache": "1.1.2", "@actions/tool-cache": "2.0.1",
"@octokit/core": "^3.5.1", "@babel/preset-env": "^7.26.0",
"@octokit/plugin-retry": "^3.0.9", "@babel/preset-typescript": "^7.26.0",
"@types/minipass": "^3.1.2", "@octokit/core": "^6.1.2",
"js-yaml": "3.13.1" "@octokit/plugin-retry": "^7.1.2",
"@types/minipass": "^3.3.5",
"js-yaml": "4.1.0",
"minimist": "^1.2.8"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^26.0.0", "@types/jest": "^29.5.14",
"@types/js-yaml": "^3.12.7", "@types/js-yaml": "^4.0.9",
"@types/node": "^12.20.41", "@types/minimist": "^1.2.5",
"@vercel/ncc": "^0.36.1", "@types/node": "^22.8.7",
"jest": "^26.0.0", "@vercel/ncc": "^0.38.3",
"prettier": "^2.7.1", "jest": "^29.7.0",
"ts-jest": "^26.0.0", "prettier": "^3.3.3",
"typescript": "3.9.5" "ts-jest": "^29.2.5",
"typescript": "5.6.3"
} }
} }
+20 -9
View File
@@ -13,6 +13,12 @@ import {
} from '../strategyHelpers/deploymentHelper' } from '../strategyHelpers/deploymentHelper'
import {DeploymentStrategy} from '../types/deploymentStrategy' import {DeploymentStrategy} from '../types/deploymentStrategy'
import {parseTrafficSplitMethod} from '../types/trafficSplitMethod' import {parseTrafficSplitMethod} from '../types/trafficSplitMethod'
export const ResourceTypeManagedCluster =
'Microsoft.ContainerService/managedClusters'
export const ResourceTypeFleet = 'Microsoft.ContainerService/fleets'
export type ClusterType =
| typeof ResourceTypeManagedCluster
| typeof ResourceTypeFleet
export async function deploy( export async function deploy(
kubectl: Kubectl, kubectl: Kubectl,
@@ -39,13 +45,25 @@ export async function deploy(
// check manifest stability // check manifest stability
core.startGroup('Checking manifest stability') core.startGroup('Checking manifest stability')
const resourceTypeInput =
core.getInput('resource-type') || ResourceTypeManagedCluster
const resourceTypes: Resource[] = getResources( const resourceTypes: Resource[] = getResources(
deployedManifestFiles, deployedManifestFiles,
models.DEPLOYMENT_TYPES.concat([ models.DEPLOYMENT_TYPES.concat([
KubernetesConstants.DiscoveryAndLoadBalancerResource.SERVICE KubernetesConstants.DiscoveryAndLoadBalancerResource.SERVICE
]) ])
) )
await checkManifestStability(kubectl, resourceTypes)
if (
resourceTypeInput !== ResourceTypeManagedCluster &&
resourceTypeInput !== ResourceTypeFleet
) {
let errMsg = `Invalid resource type: ${resourceTypeInput}. Supported resource types are: ${ResourceTypeManagedCluster} (default), ${ResourceTypeFleet}`
core.setFailed(errMsg)
throw new Error(errMsg)
}
await checkManifestStability(kubectl, resourceTypes, resourceTypeInput)
core.endGroup() core.endGroup()
// print ingresses // print ingresses
@@ -65,17 +83,10 @@ export async function deploy(
// annotate resources // annotate resources
core.startGroup('Annotating 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( await annotateAndLabelResources(
deployedManifestFiles, deployedManifestFiles,
kubectl, kubectl,
resourceTypes, resourceTypes
allPods
) )
core.endGroup() core.endGroup()
} }
+18 -20
View File
@@ -38,6 +38,7 @@ import {
TrafficSplitMethod TrafficSplitMethod
} from '../types/trafficSplitMethod' } from '../types/trafficSplitMethod'
import {parseRouteStrategy, RouteStrategy} from '../types/routeStrategy' import {parseRouteStrategy, RouteStrategy} from '../types/routeStrategy'
import {ResourceTypeFleet, ResourceTypeManagedCluster} from './deploy'
export async function promote( export async function promote(
kubectl: Kubectl, kubectl: Kubectl,
@@ -129,19 +130,13 @@ async function promoteCanary(kubectl: Kubectl, manifests: string[]) {
// annotate resources // annotate resources
core.startGroup('Annotating 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( const resources: Resource[] = getResources(
filesToAnnotate, filesToAnnotate,
models.DEPLOYMENT_TYPES.concat([ models.DEPLOYMENT_TYPES.concat([
models.DiscoveryAndLoadBalancerResource.SERVICE models.DiscoveryAndLoadBalancerResource.SERVICE
]) ])
) )
await annotateAndLabelResources(filesToAnnotate, kubectl, resources, allPods) await annotateAndLabelResources(filesToAnnotate, kubectl, resources)
core.endGroup() core.endGroup()
} }
@@ -172,6 +167,8 @@ async function promoteBlueGreen(kubectl: Kubectl, manifests: string[]) {
// checking stability of newly created deployments // checking stability of newly created deployments
core.startGroup('Checking manifest stability') core.startGroup('Checking manifest stability')
const resourceType =
core.getInput('resource-type') || ResourceTypeManagedCluster
const deployedManifestFiles = deployResult.manifestFiles const deployedManifestFiles = deployResult.manifestFiles
const resources: Resource[] = getResources( const resources: Resource[] = getResources(
deployedManifestFiles, deployedManifestFiles,
@@ -179,7 +176,19 @@ async function promoteBlueGreen(kubectl: Kubectl, manifests: string[]) {
models.DiscoveryAndLoadBalancerResource.SERVICE models.DiscoveryAndLoadBalancerResource.SERVICE
]) ])
) )
await KubernetesManifestUtility.checkManifestStability(kubectl, resources) if (
resourceType !== ResourceTypeManagedCluster &&
resourceType !== ResourceTypeFleet
) {
const errMsg = `Invalid resource type: ${resourceType}. Supported resource types are: ${ResourceTypeManagedCluster} (default), fleet`
core.setFailed(errMsg)
throw new Error(errMsg)
}
await KubernetesManifestUtility.checkManifestStability(
kubectl,
resources,
resourceType
)
core.endGroup() core.endGroup()
core.startGroup( core.startGroup(
@@ -219,17 +228,6 @@ async function promoteBlueGreen(kubectl: Kubectl, manifests: string[]) {
// annotate resources // annotate resources
core.startGroup('Annotating resources') core.startGroup('Annotating resources')
let allPods await annotateAndLabelResources(deployedManifestFiles, kubectl, resources)
try {
allPods = JSON.parse((await kubectl.getAllPods()).stdout)
} catch (e) {
core.debug(`Unable to parse pods: ${e}`)
}
await annotateAndLabelResources(
deployedManifestFiles,
kubectl,
resources,
allPods
)
core.endGroup() core.endGroup()
} }
+2 -3
View File
@@ -26,9 +26,8 @@ export async function run() {
.map((manifest) => manifest.trim()) // remove surrounding whitespace .map((manifest) => manifest.trim()) // remove surrounding whitespace
.filter((manifest) => manifest.length > 0) // remove any blanks .filter((manifest) => manifest.length > 0) // remove any blanks
const fullManifestFilePaths = await getFilesFromDirectoriesAndURLs( const fullManifestFilePaths =
manifestFilePaths await getFilesFromDirectoriesAndURLs(manifestFilePaths)
)
const kubectlPath = await getKubectlPath() const kubectlPath = await getKubectlPath()
const namespace = core.getInput('namespace') || 'default' const namespace = core.getInput('namespace') || 'default'
const isPrivateCluster = const isPrivateCluster =
@@ -77,11 +77,11 @@ export function getManifestObjects(filePaths: string[]): BlueGreenManifests {
// Manifest objects per type. All resources should be parsed and // Manifest objects per type. All resources should be parsed and
// organized before we can check if services are “routed” or not. // organized before we can check if services are “routed” or not.
filePaths.forEach((filePath: string) => { filePaths.forEach((filePath: string) => {
try {
const fileContents = fs.readFileSync(filePath).toString() const fileContents = fs.readFileSync(filePath).toString()
yaml.safeLoadAll(fileContents, (inputObject) => { yaml.loadAll(fileContents, (inputObject: any) => {
if (!!inputObject) { if (!!inputObject) {
const kind = inputObject.kind const kind = inputObject.kind
if (isDeploymentEntity(kind)) { if (isDeploymentEntity(kind)) {
deploymentEntityList.push(inputObject) deploymentEntityList.push(inputObject)
} else if (isServiceEntity(kind)) { } else if (isServiceEntity(kind)) {
@@ -93,6 +93,10 @@ export function getManifestObjects(filePaths: string[]): BlueGreenManifests {
} }
} }
}) })
} catch (error) {
core.error(`Error processing file ${filePath}: ${error.message}`)
throw error
}
}) })
serviceEntityList.forEach((inputObject: any) => { serviceEntityList.forEach((inputObject: any) => {
@@ -77,9 +77,8 @@ export async function createTrafficSplitObject(
): Promise<TrafficSplitObject> { ): Promise<TrafficSplitObject> {
// cache traffic split api version // cache traffic split api version
if (!trafficSplitAPIVersion) if (!trafficSplitAPIVersion)
trafficSplitAPIVersion = await kubectlUtils.getTrafficSplitAPIVersion( trafficSplitAPIVersion =
kubectl await kubectlUtils.getTrafficSplitAPIVersion(kubectl)
)
// retrieve annotations for TS object // retrieve annotations for TS object
const annotations = inputAnnotations const annotations = inputAnnotations
+8 -2
View File
@@ -211,13 +211,15 @@ async function cleanUpCanary(
const deletedFiles: string[] = [] const deletedFiles: string[] = []
for (const filePath of files) { for (const filePath of files) {
try {
const fileContents = fs.readFileSync(filePath).toString() const fileContents = fs.readFileSync(filePath).toString()
const parsedYaml = yaml.safeLoadAll(fileContents) const parsedYaml: any[] = yaml.loadAll(fileContents)
for (const inputObject of parsedYaml) { for (const inputObject of parsedYaml) {
const name = inputObject.metadata.name const name = inputObject.metadata.name
const kind = inputObject.kind const kind = inputObject.kind
const namespace: string | undefined = inputObject?.metadata?.namespace const namespace: string | undefined =
inputObject?.metadata?.namespace
if ( if (
isDeploymentEntity(kind) || isDeploymentEntity(kind) ||
@@ -231,6 +233,10 @@ async function cleanUpCanary(
await deleteObject(kind, baselineObjectName, namespace) await deleteObject(kind, baselineObjectName, namespace)
} }
} }
} catch (error) {
core.error(`Failed to process file ${filePath}: ${error.message}`)
throw error
}
} }
return deletedFiles return deletedFiles
+34 -10
View File
@@ -8,6 +8,7 @@ import * as canaryDeploymentHelper from './canaryHelper'
import {isDeploymentEntity} from '../../types/kubernetesTypes' import {isDeploymentEntity} from '../../types/kubernetesTypes'
import {getReplicaCount} from '../../utilities/manifestUpdateUtils' import {getReplicaCount} from '../../utilities/manifestUpdateUtils'
import {DeployResult} from '../../types/deployResult' import {DeployResult} from '../../types/deployResult'
import {K8sObject} from '../../types/k8sObject'
export async function deployPodCanary( export async function deployPodCanary(
filePaths: string[], filePaths: string[],
@@ -21,28 +22,43 @@ export async function deployPodCanary(
throw Error('Percentage must be between 0 and 100') throw Error('Percentage must be between 0 and 100')
for (const filePath of filePaths) { for (const filePath of filePaths) {
const fileContents = fs.readFileSync(filePath).toString() try {
const parsedYaml = yaml.safeLoadAll(fileContents) const fileContents = fs.readFileSync(filePath, 'utf8')
const parsedYaml = yaml.loadAll(fileContents)
for (const inputObject of parsedYaml) { for (const inputObject of parsedYaml) {
const name = inputObject.metadata.name if (
const kind = inputObject.kind inputObject &&
typeof inputObject === 'object' &&
'metadata' in inputObject &&
'kind' in inputObject &&
'spec' in inputObject &&
typeof inputObject.metadata === 'object' &&
'name' in inputObject.metadata &&
typeof inputObject.metadata.name === 'string' &&
typeof inputObject.kind === 'string'
) {
const obj = inputObject as K8sObject
const name = obj.metadata.name
const kind = obj.kind
if (!onlyDeployStable && isDeploymentEntity(kind)) { if (!onlyDeployStable && isDeploymentEntity(kind)) {
core.debug('Calculating replica count for canary') core.debug('Calculating replica count for canary')
const canaryReplicaCount = calculateReplicaCountForCanary( const canaryReplicaCount = calculateReplicaCountForCanary(
inputObject, obj,
percentage percentage
) )
core.debug('Replica count is ' + canaryReplicaCount) core.debug('Replica count is ' + canaryReplicaCount)
const newCanaryObject = canaryDeploymentHelper.getNewCanaryResource( const newCanaryObject =
inputObject, canaryDeploymentHelper.getNewCanaryResource(
obj,
canaryReplicaCount canaryReplicaCount
) )
newObjectsList.push(newCanaryObject) newObjectsList.push(newCanaryObject)
// if there's already a stable object, deploy baseline as well // if there's already a stable object, deploy baseline as well
const stableObject = await canaryDeploymentHelper.fetchResource( const stableObject =
await canaryDeploymentHelper.fetchResource(
kubectl, kubectl,
kind, kind,
name name
@@ -57,16 +73,24 @@ export async function deployPodCanary(
canaryReplicaCount canaryReplicaCount
) )
core.debug( core.debug(
'New baseline object: ' + JSON.stringify(newBaselineObject) 'New baseline object: ' +
JSON.stringify(newBaselineObject)
) )
newObjectsList.push(newBaselineObject) newObjectsList.push(newBaselineObject)
} }
} else { } else {
// deploy non deployment entity or regular deployments for promote as they are // deploy non deployment entity or regular deployments for promote as they are
newObjectsList.push(inputObject) newObjectsList.push(obj)
} }
} }
} }
} catch (error) {
core.error(
`Failed to parse YAML file at ${filePath}: ${error.message}`
)
throw error
}
}
core.debug('New objects list: ' + JSON.stringify(newObjectsList)) core.debug('New objects list: ' + JSON.stringify(newObjectsList))
const manifestFiles = fileHelper.writeObjectsToFile(newObjectsList) const manifestFiles = fileHelper.writeObjectsToFile(newObjectsList)
+33 -8
View File
@@ -11,6 +11,7 @@ import {isDeploymentEntity, isServiceEntity} from '../../types/kubernetesTypes'
import {checkForErrors} from '../../utilities/kubectlUtils' import {checkForErrors} from '../../utilities/kubectlUtils'
import {inputAnnotations} from '../../inputUtils' import {inputAnnotations} from '../../inputUtils'
import {DeployResult} from '../../types/deployResult' import {DeployResult} from '../../types/deployResult'
import {K8sObject} from '../../types/k8sObject'
const TRAFFIC_SPLIT_OBJECT_NAME_SUFFIX = '-workflow-rollout' const TRAFFIC_SPLIT_OBJECT_NAME_SUFFIX = '-workflow-rollout'
const TRAFFIC_SPLIT_OBJECT = 'TrafficSplit' const TRAFFIC_SPLIT_OBJECT = 'TrafficSplit'
@@ -36,8 +37,11 @@ export async function deploySMICanary(
const newObjectsList = [] const newObjectsList = []
for await (const filePath of filePaths) { for await (const filePath of filePaths) {
try {
const fileContents = fs.readFileSync(filePath).toString() const fileContents = fs.readFileSync(filePath).toString()
const inputObjects = yaml.safeLoadAll(fileContents) const inputObjects: K8sObject[] = yaml.loadAll(
fileContents
) as K8sObject[]
for (const inputObject of inputObjects) { for (const inputObject of inputObjects) {
const name = inputObject.metadata.name const name = inputObject.metadata.name
const kind = inputObject.kind const kind = inputObject.kind
@@ -57,7 +61,8 @@ export async function deploySMICanary(
} }
core.debug('Creating canary object') core.debug('Creating canary object')
const newCanaryObject = canaryDeploymentHelper.getNewCanaryResource( const newCanaryObject =
canaryDeploymentHelper.getNewCanaryResource(
inputObject, inputObject,
canaryReplicaCount canaryReplicaCount
) )
@@ -91,6 +96,10 @@ export async function deploySMICanary(
newObjectsList.push(inputObject) newObjectsList.push(inputObject)
} }
} }
} catch (error) {
core.error(`Failed to process file at ${filePath}: ${error.message}`)
throw error
}
} }
core.debug( core.debug(
`deploying canary objects with SMI: \n ${JSON.stringify(newObjectsList)}` `deploying canary objects with SMI: \n ${JSON.stringify(newObjectsList)}`
@@ -111,8 +120,12 @@ async function createCanaryService(
const trafficObjectsList: string[] = [] const trafficObjectsList: string[] = []
for (const filePath of filePaths) { for (const filePath of filePaths) {
try {
const fileContents = fs.readFileSync(filePath).toString() const fileContents = fs.readFileSync(filePath).toString()
const parsedYaml = yaml.safeLoadAll(fileContents) const parsedYaml: K8sObject[] = yaml.loadAll(
fileContents
) as K8sObject[]
for (const inputObject of parsedYaml) { for (const inputObject of parsedYaml) {
const name = inputObject.metadata.name const name = inputObject.metadata.name
const kind = inputObject.kind const kind = inputObject.kind
@@ -149,7 +162,8 @@ async function createCanaryService(
trafficObjectsList.push(trafficObject) trafficObjectsList.push(trafficObject)
} else { } else {
let updateTrafficObject = true let updateTrafficObject = true
const trafficObject = await canaryDeploymentHelper.fetchResource( const trafficObject =
await canaryDeploymentHelper.fetchResource(
kubectl, kubectl,
TRAFFIC_SPLIT_OBJECT, TRAFFIC_SPLIT_OBJECT,
getTrafficSplitResourceName(name) getTrafficSplitResourceName(name)
@@ -187,6 +201,10 @@ async function createCanaryService(
} }
} }
} }
} catch (error) {
core.error(`Failed to process file at ${filePath}: ${error.message}`)
throw error
}
} }
const manifestFiles = fileHelper.writeObjectsToFile(newObjectsList) const manifestFiles = fileHelper.writeObjectsToFile(newObjectsList)
@@ -224,8 +242,12 @@ async function adjustTraffic(
const trafficSplitManifests = [] const trafficSplitManifests = []
for (const filePath of manifestFilePaths) { for (const filePath of manifestFilePaths) {
try {
const fileContents = fs.readFileSync(filePath).toString() const fileContents = fs.readFileSync(filePath).toString()
const parsedYaml = yaml.safeLoadAll(fileContents) const parsedYaml: K8sObject[] = yaml.loadAll(
fileContents
) as K8sObject[]
for (const inputObject of parsedYaml) { for (const inputObject of parsedYaml) {
const name = inputObject.metadata.name const name = inputObject.metadata.name
const kind = inputObject.kind const kind = inputObject.kind
@@ -242,6 +264,10 @@ async function adjustTraffic(
) )
} }
} }
} catch (error) {
core.error(`Failed to process file at ${filePath}: ${error.message}`)
throw error
}
} }
if (trafficSplitManifests.length <= 0) { if (trafficSplitManifests.length <= 0) {
@@ -321,9 +347,8 @@ async function getTrafficSplitObject(
): Promise<string> { ): Promise<string> {
// cached version // cached version
if (!trafficSplitAPIVersion) { if (!trafficSplitAPIVersion) {
trafficSplitAPIVersion = await kubectlUtils.getTrafficSplitAPIVersion( trafficSplitAPIVersion =
kubectl await kubectlUtils.getTrafficSplitAPIVersion(kubectl)
)
} }
return JSON.stringify({ return JSON.stringify({
+33 -19
View File
@@ -10,12 +10,7 @@ import {Kubectl, Resource} from '../types/kubectl'
import {deployPodCanary} from './canary/podCanaryHelper' import {deployPodCanary} from './canary/podCanaryHelper'
import {deploySMICanary} from './canary/smiCanaryHelper' import {deploySMICanary} from './canary/smiCanaryHelper'
import {DeploymentConfig} from '../types/deploymentConfig' import {DeploymentConfig} from '../types/deploymentConfig'
import { import {deployBlueGreen} from './blueGreen/deploy'
deployBlueGreen,
deployBlueGreenIngress,
deployBlueGreenService
} from './blueGreen/deploy'
import {deployBlueGreenSMI} from './blueGreen/deploy'
import {DeploymentStrategy} from '../types/deploymentStrategy' import {DeploymentStrategy} from '../types/deploymentStrategy'
import * as core from '@actions/core' import * as core from '@actions/core'
import { import {
@@ -39,8 +34,8 @@ import {
normalizeWorkflowStrLabel normalizeWorkflowStrLabel
} from '../utilities/githubUtils' } from '../utilities/githubUtils'
import {getDeploymentConfig} from '../utilities/dockerUtils' import {getDeploymentConfig} from '../utilities/dockerUtils'
import {deploy} from '../actions/deploy'
import {DeployResult} from '../types/deployResult' import {DeployResult} from '../types/deployResult'
import {ClusterType} from '../actions/deploy'
export async function deployManifests( export async function deployManifests(
files: string[], files: string[],
@@ -116,10 +111,11 @@ function appendStableVersionLabelToResource(files: string[]): string[] {
const newObjectsList = [] const newObjectsList = []
files.forEach((filePath: string) => { files.forEach((filePath: string) => {
try {
const fileContents = fs.readFileSync(filePath).toString() const fileContents = fs.readFileSync(filePath).toString()
yaml.safeLoadAll(fileContents, function (inputObject) { yaml.loadAll(fileContents, function (inputObject) {
const {kind} = inputObject const kind = (inputObject as {kind: string}).kind
if (isDeploymentEntity(kind)) { if (isDeploymentEntity(kind)) {
const updatedObject = const updatedObject =
@@ -129,6 +125,10 @@ function appendStableVersionLabelToResource(files: string[]): string[] {
manifestFiles.push(filePath) manifestFiles.push(filePath)
} }
}) })
} catch (error) {
core.error(`Failed to parse file at ${filePath}: ${error.message}`)
throw error
}
}) })
const updatedManifestFiles = fileHelper.writeObjectsToFile(newObjectsList) const updatedManifestFiles = fileHelper.writeObjectsToFile(newObjectsList)
@@ -139,16 +139,20 @@ function appendStableVersionLabelToResource(files: string[]): string[] {
export async function checkManifestStability( export async function checkManifestStability(
kubectl: Kubectl, kubectl: Kubectl,
resources: Resource[] resources: Resource[],
resourceType: ClusterType
): Promise<void> { ): Promise<void> {
await KubernetesManifestUtility.checkManifestStability(kubectl, resources) await KubernetesManifestUtility.checkManifestStability(
kubectl,
resources,
resourceType
)
} }
export async function annotateAndLabelResources( export async function annotateAndLabelResources(
files: string[], files: string[],
kubectl: Kubectl, kubectl: Kubectl,
resourceTypes: Resource[], resourceTypes: Resource[]
allPods: any
) { ) {
const defaultWorkflowFileName = 'k8s-deploy-failed-workflow-annotation' const defaultWorkflowFileName = 'k8s-deploy-failed-workflow-annotation'
const githubToken = core.getInput('token') const githubToken = core.getInput('token')
@@ -163,15 +167,20 @@ export async function annotateAndLabelResources(
const deploymentConfig = await getDeploymentConfig() const deploymentConfig = await getDeploymentConfig()
const annotationKeyLabel = getWorkflowAnnotationKeyLabel() const annotationKeyLabel = getWorkflowAnnotationKeyLabel()
const shouldAnnotateResources = !(
core.getInput('annotate-resources').toLowerCase() === 'false'
)
if (shouldAnnotateResources) {
await annotateResources( await annotateResources(
files, files,
kubectl, kubectl,
resourceTypes, resourceTypes,
allPods,
annotationKeyLabel, annotationKeyLabel,
workflowFilePath, workflowFilePath,
deploymentConfig deploymentConfig
).catch((err) => core.warning(`Failed to annotate resources: ${err} `)) ).catch((err) => core.warning(`Failed to annotate resources: ${err} `))
}
await labelResources(files, kubectl, annotationKeyLabel).catch((err) => await labelResources(files, kubectl, annotationKeyLabel).catch((err) =>
core.warning(`Failed to label resources: ${err}`) core.warning(`Failed to label resources: ${err}`)
@@ -182,7 +191,6 @@ async function annotateResources(
files: string[], files: string[],
kubectl: Kubectl, kubectl: Kubectl,
resourceTypes: Resource[], resourceTypes: Resource[],
allPods: any,
annotationKey: string, annotationKey: string,
workflowFilePath: string, workflowFilePath: string,
deploymentConfig: DeploymentConfig deploymentConfig: DeploymentConfig
@@ -196,15 +204,20 @@ async function annotateResources(
) )
if (core.isDebug()) { if (core.isDebug()) {
try {
core.debug(`files getting annotated are ${JSON.stringify(files)}`) core.debug(`files getting annotated are ${JSON.stringify(files)}`)
for (const filePath of files) { for (const filePath of files) {
core.debug('printing objects getting annotated...') core.debug('printing objects getting annotated...')
const fileContents = fs.readFileSync(filePath).toString() const fileContents = fs.readFileSync(filePath).toString()
const inputObjects = yaml.safeLoadAll(fileContents) const inputObjects = yaml.loadAll(fileContents)
for (const inputObject of inputObjects) { for (const inputObject of inputObjects) {
core.debug(`object: ${JSON.stringify(inputObject)}`) core.debug(`object: ${JSON.stringify(inputObject)}`)
} }
} }
} catch (error) {
core.error(`Failed to load and parse files: ${error.message}`)
throw error
}
} }
const annotationKeyValStr = `${annotationKey}=${getWorkflowAnnotations( const annotationKeyValStr = `${annotationKey}=${getWorkflowAnnotations(
@@ -226,11 +239,13 @@ async function annotateResources(
) )
) )
} }
for (const file of files) { for (const file of files) {
try { try {
const annotateResult = await kubectl.annotateFiles( const annotateResult = await kubectl.annotateFiles(
file, file,
annotationKeyValStr annotationKeyValStr,
namespace
) )
annotateResults.push(annotateResult) annotateResults.push(annotateResult)
} catch (e) { } catch (e) {
@@ -249,8 +264,7 @@ async function annotateResources(
resource.type, resource.type,
resource.name, resource.name,
resource.namespace, resource.namespace,
annotationKeyValStr, annotationKeyValStr
allPods
) )
).forEach((execResult) => annotateResults.push(execResult)) ).forEach((execResult) => annotateResults.push(execResult))
} }
-11
View File
@@ -39,17 +39,6 @@ const testNamespace = 'testNamespace'
const defaultNamespace = 'default' const defaultNamespace = 'default'
const otherNamespace = 'otherns' const otherNamespace = 'otherns'
describe('Kubectl class', () => { 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', () => { describe('with a success exec return in testNamespace', () => {
const kubectl = new Kubectl(kubectlPath, testNamespace) const kubectl = new Kubectl(kubectlPath, testNamespace)
const execReturn = {exitCode: 0, stdout: 'Output', stderr: ''} const execReturn = {exitCode: 0, stdout: 'Output', stderr: ''}
+33 -4
View File
@@ -1,8 +1,14 @@
import {PrivateKubectl} from './privatekubectl' import * as fileUtils from '../utilities/fileUtils'
import fs from 'node:fs'
import {
PrivateKubectl,
extractFileNames,
replaceFileNamesWithShallowNamesRelativeToTemp
} from './privatekubectl'
import * as exec from '@actions/exec' import * as exec from '@actions/exec'
describe('Private kubectl', () => { 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 /tmp/testdir/test.yml,/tmp/test2.yml,/tmp/testdir/subdir/test3.yml -f /tmp/test4.yml --filename /tmp/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/test.yml"],"helmChartPaths":[],"provider":"GitHub"} --overwrite --namespace test-3498366832`
const mockKube = new PrivateKubectl( const mockKube = new PrivateKubectl(
'kubectlPath', 'kubectlPath',
'namespace', 'namespace',
@@ -11,9 +17,32 @@ describe('Private kubectl', () => {
'resourceName' 'resourceName'
) )
const spy = jest
.spyOn(fileUtils, 'getTempDirectory')
.mockImplementation(() => {
return '/tmp'
})
jest.spyOn(fs, 'writeFileSync').mockImplementation(() => {})
jest.spyOn(fs, 'readFileSync').mockImplementation((filename) => {
return 'test contents'
})
it('should extract filenames correctly', () => { it('should extract filenames correctly', () => {
expect(mockKube.extractFilesnames(testString)).toEqual( expect(extractFileNames(testString)).toEqual([
'test.yml test2.yml test3.yml test4.yml test5.yml' '/tmp/testdir/test.yml',
'/tmp/test2.yml',
'/tmp/testdir/subdir/test3.yml',
'/tmp/test4.yml',
'/tmp/test5.yml'
])
})
it('should replace filenames with shallow names for relative locations in tmp correctly', () => {
expect(
replaceFileNamesWithShallowNamesRelativeToTemp(testString)
).toEqual(
`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/test.yml"],"helmChartPaths":[],"provider":"GitHub"} --overwrite --namespace test-3498366832`
) )
}) })
+64 -78
View File
@@ -1,10 +1,10 @@
import {Kubectl} from './kubectl' import {Kubectl} from './kubectl'
import * as minimist from 'minimist' import minimist from 'minimist'
import {ExecOptions, ExecOutput, getExecOutput} from '@actions/exec' import {ExecOptions, ExecOutput, getExecOutput} from '@actions/exec'
import * as core from '@actions/core' import * as core from '@actions/core'
import * as os from 'os' import fs from 'node:fs'
import * as fs from 'fs'
import * as path from 'path' import * as path from 'path'
import {getTempDirectory} from '../utilities/fileUtils'
export class PrivateKubectl extends Kubectl { export class PrivateKubectl extends Kubectl {
protected async execute(args: string[], silent: boolean = false) { protected async execute(args: string[], silent: boolean = false) {
@@ -18,8 +18,7 @@ export class PrivateKubectl extends Kubectl {
} }
if (this.containsFilenames(kubectlCmd)) { if (this.containsFilenames(kubectlCmd)) {
// For private clusters, files will referenced solely by their basename kubectlCmd = replaceFileNamesWithShallowNamesRelativeToTemp(kubectlCmd)
kubectlCmd = this.replaceFilnamesWithBasenames(kubectlCmd)
addFileFlag = true addFileFlag = true
} }
@@ -43,22 +42,9 @@ export class PrivateKubectl extends Kubectl {
] ]
if (addFileFlag) { if (addFileFlag) {
const filenames = this.extractFilesnames(kubectlCmd).split(' ') const tempDirectory = getTempDirectory()
eo.cwd = path.join(tempDirectory, 'manifests')
const tempDirectory =
process.env['runner.tempDirectory'] || os.tmpdir() + '/manifests'
eo.cwd = tempDirectory
privateClusterArgs.push(...['--file', '.']) privateClusterArgs.push(...['--file', '.'])
let filenamesArr = filenames[0].split(',')
for (let index = 0; index < filenamesArr.length; index++) {
const file = filenamesArr[index]
if (!file) {
continue
}
this.moveFileToTempManifestDir(file)
}
} }
core.debug( core.debug(
@@ -95,34 +81,78 @@ export class PrivateKubectl extends Kubectl {
} as ExecOutput } as ExecOutput
} }
private replaceFilnamesWithBasenames(kubectlCmd: string) { private containsFilenames(str: string) {
let exFilenames = this.extractFilesnames(kubectlCmd) return str.includes('-f ') || str.includes('filename ')
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() function createTempManifestsDirectory(): string {
const manifestsDirPath = path.join(getTempDirectory(), 'manifests')
if (!fs.existsSync(manifestsDirPath)) {
fs.mkdirSync(manifestsDirPath, {recursive: true})
}
let result = kubectlCmd.replace(exFilenames, baseFilenames) return manifestsDirPath
}
export function replaceFileNamesWithShallowNamesRelativeToTemp(
kubectlCmd: string
) {
let filenames = extractFileNames(kubectlCmd)
core.debug(`filenames originally provided in kubectl command: ${filenames}`)
let relativeShallowNames = filenames.map((filename) => {
const relativeName = path.relative(getTempDirectory(), filename)
const relativePathElements = relativeName.split(path.sep)
const shallowName = relativePathElements.join('-')
// make manifests dir in temp if it doesn't already exist
const manifestsTempDir = createTempManifestsDirectory()
const shallowPath = path.join(manifestsTempDir, shallowName)
core.debug(
`moving contents from ${filename} to shallow location at ${shallowPath}`
)
core.debug(`reading contents from ${filename}`)
const contents = fs.readFileSync(filename).toString()
core.debug(`writing contents to new path ${shallowPath}`)
fs.writeFileSync(shallowPath, contents)
return shallowName
})
let result = kubectlCmd
if (filenames.length != relativeShallowNames.length) {
throw Error(
'replacing filenames with relative path from temp dir, ' +
filenames.length +
' filenames != ' +
relativeShallowNames.length +
'basenames'
)
}
for (let index = 0; index < filenames.length; index++) {
result = result.replace(filenames[index], relativeShallowNames[index])
}
return result return result
} }
public extractFilesnames(strToParse: string) { export function extractFileNames(strToParse: string) {
const fileNames: string[] = [] const fileNames: string[] = []
const argv = minimist(strToParse.split(' ')) const argv = minimist(strToParse.split(' '))
const fArg = 'f' const fArg = 'f'
const filenameArg = 'filename' const filenameArg = 'filename'
fileNames.push(...this.extractFilesFromMinimist(argv, fArg)) fileNames.push(...extractFilesFromMinimist(argv, fArg))
fileNames.push(...this.extractFilesFromMinimist(argv, filenameArg)) fileNames.push(...extractFilesFromMinimist(argv, filenameArg))
return fileNames.join(' ') return fileNames
} }
private extractFilesFromMinimist(argv, arg: string): string[] { export function extractFilesFromMinimist(argv, arg: string): string[] {
if (!argv[arg]) { if (!argv[arg]) {
return [] return []
} }
@@ -137,47 +167,3 @@ export class PrivateKubectl extends Kubectl {
return toReturn return toReturn
} }
private containsFilenames(str: string) {
return str.includes('-f ') || str.includes('filename ')
}
private createTempManifestsDirectory() {
const manifestsDir = '/tmp/manifests'
if (!fs.existsSync('/tmp/manifests')) {
fs.mkdirSync('/tmp/manifests', {recursive: true})
}
}
private moveFileToTempManifestDir(file: string) {
this.createTempManifestsDirectory()
if (!fs.existsSync('/tmp/' + file)) {
core.debug(
'/tmp/' +
file +
' does not exist, and therefore cannot be moved to the manifest directory'
)
}
fs.copyFile('/tmp/' + file, '/tmp/manifests/' + file, function (err) {
if (err) {
core.debug(
'Could not rename ' +
'/tmp/' +
file +
' to ' +
'/tmp/manifests/' +
file +
' ERROR: ' +
err
)
return
}
core.debug(
"Successfully moved file '" +
file +
"' from /tmp to /tmp/manifest directory"
)
})
}
}
+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 imageDockerfilePathMap: {[id: string]: string} = {}
const pullImages = !(core.getInput('pull-images').toLowerCase() === 'false') const pullImages = !(core.getInput('pull-images').toLowerCase() === 'false')
+36 -21
View File
@@ -1,22 +1,19 @@
import { import * as fileUtils from './fileUtils'
getFilesFromDirectoriesAndURLs,
getTempDirectory,
urlFileKind,
writeYamlFromURLToFile
} from './fileUtils'
import * as yaml from 'js-yaml' import * as yaml from 'js-yaml'
import * as fs from 'fs' import fs from 'node:fs'
import * as path from 'path' import * as path from 'path'
import {succeeded} from '../types/errorable' import {K8sObject} from '../types/k8sObject'
const sampleYamlUrl = const sampleYamlUrl =
'https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/controllers/nginx-deployment.yaml' 'https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/controllers/nginx-deployment.yaml'
describe('File utils', () => { describe('File utils', () => {
test('correctly parses a yaml file from a URL', async () => { test('correctly parses a yaml file from a URL', async () => {
const tempFile = await writeYamlFromURLToFile(sampleYamlUrl, 0) const tempFile = await fileUtils.writeYamlFromURLToFile(sampleYamlUrl, 0)
const fileContents = fs.readFileSync(tempFile).toString() const fileContents = fs.readFileSync(tempFile).toString()
const inputObjects = yaml.safeLoadAll(fileContents) const inputObjects: K8sObject[] = yaml.loadAll(
fileContents
) as K8sObject[]
expect(inputObjects).toHaveLength(1) expect(inputObjects).toHaveLength(1)
for (const obj of inputObjects) { for (const obj of inputObjects) {
@@ -30,34 +27,34 @@ describe('File utils', () => {
const testPath = path.join('test', 'unit', 'manifests') const testPath = path.join('test', 'unit', 'manifests')
await expect( await expect(
getFilesFromDirectoriesAndURLs([testPath, badUrl]) fileUtils.getFilesFromDirectoriesAndURLs([testPath, badUrl])
).rejects.toThrow() ).rejects.toThrow()
}) })
it('detects files in nested directories and ignores non-manifest files and empty dirs', async () => { it('detects files in nested directories with the same name and ignores non-manifest files and empty dirs', async () => {
const testPath = path.join('test', 'unit', 'manifests') const testPath = path.join('test', 'unit', 'manifests')
const testSearch: string[] = await getFilesFromDirectoriesAndURLs([ const testSearch: string[] =
await fileUtils.getFilesFromDirectoriesAndURLs([
testPath, testPath,
sampleYamlUrl sampleYamlUrl
]) ])
const expectedManifests = [ const expectedManifests = [
'test/unit/manifests/manifest_test_dir/another_layer/deep-ingress.yaml', 'test/unit/manifests/manifest_test_dir/another_layer/test-ingress.yaml',
'test/unit/manifests/manifest_test_dir/another_layer/deep-service.yaml', 'test/unit/manifests/manifest_test_dir/another_layer/nested-test-service.yaml',
'test/unit/manifests/manifest_test_dir/nested-test-service.yaml', 'test/unit/manifests/manifest_test_dir/nested-test-service.yaml',
'test/unit/manifests/test-ingress.yml', 'test/unit/manifests/test-ingress.yml',
'test/unit/manifests/test-ingress-new.yml', 'test/unit/manifests/test-ingress-new.yml',
'test/unit/manifests/test-service.yml' 'test/unit/manifests/test-service.yml'
] ]
// is there a more efficient way to test equality w random order?
expect(testSearch).toHaveLength(8) expect(testSearch).toHaveLength(8)
expectedManifests.forEach((fileName) => { expectedManifests.forEach((fileName) => {
if (fileName.startsWith('test/unit')) { if (fileName.startsWith('test/unit')) {
expect(testSearch).toContain(fileName) expect(testSearch).toContain(fileName)
} else { } else {
expect(fileName.includes(urlFileKind)).toBe(true) expect(fileName.includes(fileUtils.urlFileKind)).toBe(true)
expect(fileName.startsWith(getTempDirectory())) expect(fileName.startsWith(fileUtils.getTempDirectory()))
} }
}) })
}) })
@@ -72,7 +69,7 @@ describe('File utils', () => {
) )
expect( expect(
getFilesFromDirectoriesAndURLs([badPath, goodPath]) fileUtils.getFilesFromDirectoriesAndURLs([badPath, goodPath])
).rejects.toThrowError() ).rejects.toThrowError()
}) })
@@ -92,7 +89,7 @@ describe('File utils', () => {
) )
expect( expect(
await getFilesFromDirectoriesAndURLs([ await fileUtils.getFilesFromDirectoriesAndURLs([
outerPath, outerPath,
fileAtOuter, fileAtOuter,
innerPath innerPath
@@ -102,6 +99,24 @@ describe('File utils', () => {
it('throws an error for an invalid URL', async () => { it('throws an error for an invalid URL', async () => {
const badUrl = 'https://www.github.com' const badUrl = 'https://www.github.com'
await expect(writeYamlFromURLToFile(badUrl, 0)).rejects.toBeTruthy() await expect(
fileUtils.writeYamlFromURLToFile(badUrl, 0)
).rejects.toBeTruthy()
})
})
describe('moving files to temp', () => {
it('correctly moves the contents of a file to the temporary directory', () => {
jest.spyOn(fs, 'writeFileSync').mockImplementation(() => {})
jest.spyOn(fs, 'readFileSync').mockImplementation((filename) => {
return 'test contents'
})
const originalFilePath = path.join('path', 'in', 'repo')
const output = fileUtils.moveFileToTmpDir(originalFilePath)
expect(output).toEqual(
path.join(fileUtils.getTempDirectory(), '/path/in/repo')
)
}) })
}) })
+26 -6
View File
@@ -1,4 +1,4 @@
import * as fs from 'fs' import fs from 'node:fs'
import * as https from 'https' import * as https from 'https'
import * as path from 'path' import * as path from 'path'
import * as core from '@actions/core' import * as core from '@actions/core'
@@ -23,7 +23,7 @@ export function writeObjectsToFile(inputObjects: any[]): string[] {
const inputObjectString = JSON.stringify(inputObject) const inputObjectString = JSON.stringify(inputObject)
if (inputObject?.metadata?.name) { if (inputObject?.metadata?.name) {
const fileName = getManifestFileName( const fileName = getNewTempManifestFileName(
inputObject.kind, inputObject.kind,
inputObject.metadata.name inputObject.metadata.name
) )
@@ -52,7 +52,7 @@ export function writeManifestToFile(
): string { ): string {
if (inputObjectString) { if (inputObjectString) {
try { try {
const fileName = getManifestFileName(kind, name) const fileName = getNewTempManifestFileName(kind, name)
fs.writeFileSync(path.join(fileName), inputObjectString) fs.writeFileSync(path.join(fileName), inputObjectString)
return fileName return fileName
} catch (ex) { } catch (ex) {
@@ -63,7 +63,27 @@ export function writeManifestToFile(
} }
} }
function getManifestFileName(kind: string, name: string) { export function moveFileToTmpDir(originalFilepath: string) {
const tempDirectory = getTempDirectory()
const newPath = path.join(tempDirectory, originalFilepath)
core.debug(`reading original contents from path: ${originalFilepath}`)
const contents = fs.readFileSync(originalFilepath).toString()
const dirName = path.dirname(newPath)
if (!fs.existsSync(dirName)) {
core.debug(`path ${dirName} doesn't exist yet, making new dir...`)
fs.mkdirSync(dirName, {recursive: true})
}
core.debug(`writing contents to new path ${newPath}`)
fs.writeFileSync(path.join(newPath), contents)
core.debug(`moved contents from ${originalFilepath} to ${newPath}`)
return newPath
}
function getNewTempManifestFileName(kind: string, name: string) {
const filePath = `${kind}_${name}_${getCurrentTime().toString()}` const filePath = `${kind}_${name}_${getCurrentTime().toString()}`
const tempDirectory = getTempDirectory() const tempDirectory = getTempDirectory()
return path.join(tempDirectory, path.basename(filePath)) return path.join(tempDirectory, path.basename(filePath))
@@ -130,7 +150,7 @@ export async function writeYamlFromURLToFile(
) )
} }
const targetPath = getManifestFileName( const targetPath = getNewTempManifestFileName(
urlFileKind, urlFileKind,
fileNumber.toString() fileNumber.toString()
) )
@@ -163,7 +183,7 @@ function verifyYaml(filepath: string, url: string): Errorable<K8sObject[]> {
const fileContents = fs.readFileSync(filepath).toString() const fileContents = fs.readFileSync(filepath).toString()
let inputObjects let inputObjects
try { try {
inputObjects = yaml.safeLoadAll(fileContents) inputObjects = yaml.loadAll(fileContents)
} catch (e) { } catch (e) {
return { return {
succeeded: false, succeeded: false,
+9 -2
View File
@@ -61,8 +61,7 @@ export async function annotateChildPods(
resourceType: string, resourceType: string,
resourceName: string, resourceName: string,
namespace: string | undefined, namespace: string | undefined,
annotationKeyValStr: string, annotationKeyValStr: string
allPods
): Promise<ExecOutput[]> { ): Promise<ExecOutput[]> {
let owner = resourceName let owner = resourceName
if (resourceType.toLowerCase().indexOf('deployment') > -1) { if (resourceType.toLowerCase().indexOf('deployment') > -1) {
@@ -70,6 +69,14 @@ export async function annotateChildPods(
} }
const commandExecutionResults = [] 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) { if (allPods?.items && allPods.items?.length > 0) {
allPods.items.forEach((pod) => { allPods.items.forEach((pod) => {
const owners = pod?.metadata?.ownerReferences const owners = pod?.metadata?.ownerReferences
@@ -0,0 +1,52 @@
import * as manifestStabilityUtils from './manifestStabilityUtils'
import {Kubectl} from '../types/kubectl'
import {ResourceTypeFleet, ResourceTypeManagedCluster} from '../actions/deploy'
import {ExecOutput} from '@actions/exec'
import {exitCode, stdout} from 'process'
describe('manifestStabilityUtils', () => {
const kc = new Kubectl('')
const resources = [
{
type: 'deployment',
name: 'test',
namespace: 'default'
}
]
it('should return immediately if the resource type is fleet', async () => {
const spy = jest.spyOn(manifestStabilityUtils, 'checkManifestStability')
const checkRolloutStatusSpy = jest.spyOn(kc, 'checkRolloutStatus')
await manifestStabilityUtils.checkManifestStability(
kc,
resources,
ResourceTypeFleet
)
expect(checkRolloutStatusSpy).not.toHaveBeenCalled()
expect(spy).toHaveReturned()
})
it('should run fully if the resource type is managedCluster', async () => {
const spy = jest.spyOn(manifestStabilityUtils, 'checkManifestStability')
const checkRolloutStatusSpy = jest
.spyOn(kc, 'checkRolloutStatus')
.mockImplementation(() => {
return new Promise<ExecOutput>((resolve, reject) => {
resolve({
exitCode: 0,
stderr: '',
stdout: ''
})
})
})
await manifestStabilityUtils.checkManifestStability(
kc,
resources,
ResourceTypeManagedCluster
)
expect(checkRolloutStatusSpy).toHaveBeenCalled()
expect(spy).toHaveReturned()
})
})
+8 -1
View File
@@ -3,14 +3,21 @@ import * as KubernetesConstants from '../types/kubernetesTypes'
import {Kubectl, Resource} from '../types/kubectl' import {Kubectl, Resource} from '../types/kubectl'
import {checkForErrors} from './kubectlUtils' import {checkForErrors} from './kubectlUtils'
import {sleep} from './timeUtils' import {sleep} from './timeUtils'
import {ClusterType, ResourceTypeFleet} from '../actions/deploy'
const IS_SILENT = false const IS_SILENT = false
const POD = 'pod' const POD = 'pod'
export async function checkManifestStability( export async function checkManifestStability(
kubectl: Kubectl, kubectl: Kubectl,
resources: Resource[] resources: Resource[],
clusterTyper: ClusterType
): Promise<void> { ): Promise<void> {
// Skip if resource type is microsoft.containerservice/fleets
if (clusterTyper === ResourceTypeFleet) {
core.info(`Skipping checkManifestStability for ${ResourceTypeFleet}`)
return
}
let rolloutStatusHasErrors = false let rolloutStatusHasErrors = false
for (let i = 0; i < resources.length; i++) { for (let i = 0; i < resources.length; i++) {
const resource = resources[i] const resource = resources[i]
+28
View File
@@ -0,0 +1,28 @@
import * as fileUtils from './fileUtils'
import * as manifestUpdateUtils from './manifestUpdateUtils'
import * as path from 'path'
import * as fs from 'fs'
describe('manifestUpdateUtils', () => {
jest.spyOn(fileUtils, 'moveFileToTmpDir').mockImplementation((filename) => {
return path.join('/tmp', filename)
})
jest.spyOn(fs, 'writeFileSync').mockImplementation(() => {})
jest.spyOn(fs, 'readFileSync').mockImplementation((filename) => {
return 'test contents'
})
it('should place all files within the temp dir with the same path that they have in the repo', () => {
const originalFilePaths: string[] = [
'path/in/repo/test.txt',
'path/deeper/in/repo/test.txt'
]
const expected: string[] = [
'/tmp/path/in/repo/test.txt',
'/tmp/path/deeper/in/repo/test.txt'
]
const newFilePaths =
manifestUpdateUtils.moveFilesToTmpDir(originalFilePaths)
expect(newFilePaths).toEqual(expected)
})
})
+30 -12
View File
@@ -3,7 +3,7 @@ import * as fs from 'fs'
import * as yaml from 'js-yaml' import * as yaml from 'js-yaml'
import * as path from 'path' import * as path from 'path'
import * as fileHelper from './fileUtils' import * as fileHelper from './fileUtils'
import {getTempDirectory} from './fileUtils' import {moveFileToTmpDir} from './fileUtils'
import { import {
InputObjectKindNotDefinedError, InputObjectKindNotDefinedError,
InputObjectMetadataNotDefinedError, InputObjectMetadataNotDefinedError,
@@ -20,16 +20,21 @@ import {
setImagePullSecrets setImagePullSecrets
} from './manifestPullSecretUtils' } from './manifestPullSecretUtils'
import {Resource} from '../types/kubectl' import {Resource} from '../types/kubectl'
import {K8sObject} from '../types/k8sObject'
export function updateManifestFiles(manifestFilePaths: string[]) { export function updateManifestFiles(manifestFilePaths: string[]) {
if (manifestFilePaths?.length === 0) { if (manifestFilePaths?.length === 0) {
throw new Error('Manifest files not provided') throw new Error('Manifest files not provided')
} }
// move original set of input files to tmp dir
const manifestFilesInTempDir = moveFilesToTmpDir(manifestFilePaths)
// update container images // update container images
const containers: string[] = core.getInput('images').split('\n') const containers: string[] = core.getInput('images').split('\n')
const manifestFiles = updateContainerImagesInManifestFiles( const manifestFiles = updateContainerImagesInManifestFiles(
manifestFilePaths, manifestFilesInTempDir,
containers containers
) )
@@ -41,6 +46,12 @@ export function updateManifestFiles(manifestFilePaths: string[]) {
return updateImagePullSecretsInManifestFiles(manifestFiles, imagePullSecrets) return updateImagePullSecretsInManifestFiles(manifestFiles, imagePullSecrets)
} }
export function moveFilesToTmpDir(filepaths: string[]): string[] {
return filepaths.map((filename) => {
return moveFileToTmpDir(filename)
})
}
export function UnsetClusterSpecificDetails(resource: any) { export function UnsetClusterSpecificDetails(resource: any) {
if (!resource) { if (!resource) {
return return
@@ -70,12 +81,9 @@ function updateContainerImagesInManifestFiles(
): string[] { ): string[] {
if (filePaths?.length <= 0) return filePaths if (filePaths?.length <= 0) return filePaths
const newFilePaths = []
// update container images // update container images
filePaths.forEach((filePath: string) => { filePaths.forEach((filePath: string) => {
let contents = fs.readFileSync(filePath).toString() let contents = fs.readFileSync(filePath).toString()
containers.forEach((container: string) => { containers.forEach((container: string) => {
let [imageName] = container.split(':') let [imageName] = container.split(':')
if (imageName.indexOf('@') > 0) { if (imageName.indexOf('@') > 0) {
@@ -91,13 +99,10 @@ function updateContainerImagesInManifestFiles(
}) })
// write updated files // write updated files
const tempDirectory = getTempDirectory() fs.writeFileSync(path.join(filePath), contents)
const fileName = path.join(tempDirectory, path.basename(filePath))
fs.writeFileSync(path.join(fileName), contents)
newFilePaths.push(fileName)
}) })
return newFilePaths return filePaths
} }
/* /*
@@ -270,8 +275,12 @@ export function getResources(
const resources: Resource[] = [] const resources: Resource[] = []
filePaths.forEach((filePath: string) => { filePaths.forEach((filePath: string) => {
try {
const fileContents = fs.readFileSync(filePath).toString() const fileContents = fs.readFileSync(filePath).toString()
yaml.safeLoadAll(fileContents, (inputObject) => { const inputObjects: K8sObject[] = yaml.loadAll(
fileContents
) as K8sObject[]
inputObjects.forEach((inputObject) => {
const inputObjectKind = inputObject?.kind || '' const inputObjectKind = inputObject?.kind || ''
if ( if (
filterResourceTypes.filter( filterResourceTypes.filter(
@@ -285,6 +294,10 @@ export function getResources(
}) })
} }
}) })
} catch (error) {
core.error(`Failed to process file at ${filePath}: ${error.message}`)
throw error
}
}) })
return resources return resources
@@ -298,8 +311,9 @@ function updateImagePullSecretsInManifestFiles(
const newObjectsList = [] const newObjectsList = []
filePaths.forEach((filePath: string) => { filePaths.forEach((filePath: string) => {
try {
const fileContents = fs.readFileSync(filePath).toString() const fileContents = fs.readFileSync(filePath).toString()
yaml.safeLoadAll(fileContents, (inputObject: any) => { yaml.loadAll(fileContents, (inputObject: any) => {
if (inputObject?.kind) { if (inputObject?.kind) {
const {kind} = inputObject const {kind} = inputObject
if (isWorkloadEntity(kind)) { if (isWorkloadEntity(kind)) {
@@ -308,6 +322,10 @@ function updateImagePullSecretsInManifestFiles(
newObjectsList.push(inputObject) newObjectsList.push(inputObject)
} }
}) })
} catch (error) {
core.error(`Failed to process file at ${filePath}: ${error.message}`)
throw error
}
}) })
return fileHelper.writeObjectsToFile(newObjectsList) return fileHelper.writeObjectsToFile(newObjectsList)
+2 -2
View File
@@ -7,7 +7,7 @@ def delete(kind, name, namespace):
if (name == "all"): if (name == "all"):
print('kubectl delete --all' + kind + ' -n ' + namespace) print('kubectl delete --all' + kind + ' -n ' + namespace)
deletion = subprocess.Popen( deletion = subprocess.Popen(
['kubectl', 'delete', kind, name, '--namespace', namespace]) ['kubectl', 'delete', kind, '--all', '--namespace', namespace])
result, err = deletion.communicate() result, err = deletion.communicate()
else: else:
print('kubectl delete ' + kind + ' ' + name + ' -n ' + namespace) print('kubectl delete ' + kind + ' ' + name + ' -n ' + namespace)
@@ -21,7 +21,7 @@ def delete(kind, name, namespace):
def main(): def main():
kind = sys.argv[1] kind = sys.argv[1]
name = sys.argv[2] name = sys.argv[2]
namespace = 'test-' + sys.argv[3] namespace = sys.argv[3]
delete(kind, name, namespace) delete(kind, name, namespace)
+21 -16
View File
@@ -41,10 +41,6 @@ def parseArgs(sysArgs):
argsDict[labelsKey] = stringListToDict( argsDict[labelsKey] = stringListToDict(
argsDict[labelsKey].split(","), ":") argsDict[labelsKey].split(","), ":")
if annotationsKey in argsDict:
argsDict[annotationsKey] = stringListToDict(
argsDict[annotationsKey].split(","), ":")
if selectorLabelsKey in argsDict: if selectorLabelsKey in argsDict:
argsDict[selectorLabelsKey] = stringListToDict( argsDict[selectorLabelsKey] = stringListToDict(
argsDict[selectorLabelsKey].split(","), ":") argsDict[selectorLabelsKey].split(","), ":")
@@ -60,6 +56,9 @@ def parseArgs(sysArgs):
if ingressServicesKey in argsDict: if ingressServicesKey in argsDict:
argsDict[ingressServicesKey] = argsDict[ingressServicesKey].split(",") argsDict[ingressServicesKey] = argsDict[ingressServicesKey].split(",")
if annotationsKey in argsDict:
argsDict[annotationsKey] = argsDict[annotationsKey].split(",")
return argsDict return argsDict
@@ -98,14 +97,14 @@ def verifyDeployment(deployment, parsedArgs):
return dictMatch, msg return dictMatch, msg
if annotationsKey in parsedArgs: if annotationsKey in parsedArgs:
dictMatch, msg = compareDicts( if len(parsedArgs[annotationsKey]) != len(deployment['metadata']['annotations']):
deployment['metadata']['annotations'], parsedArgs[annotationsKey], annotationsKey) return False, f"expected {len(parsedArgs[annotationsKey])} annotations but found {len(deployment['metadata']['annotations'])}"
if not dictMatch: keysPresent, msg = validateKeyPresence(
return dictMatch, msg deployment['metadata']['annotations'], parsedArgs[annotationsKey])
if not keysPresent:
return keysPresent, msg
return True, "" return True, ""
def verifyService(service, parsedArgs): def verifyService(service, parsedArgs):
# test selector labels, labels, annotations # test selector labels, labels, annotations
if not selectorLabelsKey in parsedArgs: if not selectorLabelsKey in parsedArgs:
@@ -124,10 +123,10 @@ def verifyService(service, parsedArgs):
return dictMatch, msg return dictMatch, msg
if annotationsKey in parsedArgs: if annotationsKey in parsedArgs:
dictMatch, msg = compareDicts( keysPresent, msg = validateKeyPresence(
service['metadata']['annotations'], parsedArgs[annotationsKey], annotationsKey) service['metadata']['annotations'], parsedArgs[annotationsKey])
if not dictMatch: if not keysPresent:
return dictMatch, msg return keysPresent, msg
return True, "" return True, ""
@@ -188,6 +187,13 @@ def compareDicts(actual: dict, expected: dict, paramName=""):
return True, "" 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(): def main():
parsedArgs: dict = parseArgs(sys.argv[1:]) parsedArgs: dict = parseArgs(sys.argv[1:])
@@ -226,8 +232,7 @@ def main():
getAllObjectsCmd = azPrefix + 'kubectl get '+kind+' -n '+namespace getAllObjectsCmd = azPrefix + 'kubectl get '+kind+' -n '+namespace
if not azPrefix == "": if not azPrefix == "":
getAllObjectsCmd = azPrefix + "'{getAllObjectsCmd}'" # add extra set of quotes getAllObjectsCmd = azPrefix + "'{getAllObjectsCmd}'" # add extra set of quotes
cmd = + "'" + cmd + "'" foundObjects = os.popen(getAllObjectsCmd).read()
foundObjects = os.popen().read()
suffix = f"resources of type {kind}: {foundObjects}" suffix = f"resources of type {kind}: {foundObjects}"
sys.exit(msg + " " + suffix) sys.exit(msg + " " + suffix)
@@ -0,0 +1,33 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment3
labels:
app: nginx3
spec:
replicas: 1
selector:
matchLabels:
app: nginx3
template:
metadata:
labels:
app: nginx3
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service3
spec:
selector:
app: nginx3
ports:
- protocol: TCP
port: 80
targetPort: 80
+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
+2 -1
View File
@@ -1,7 +1,8 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "ES6", "target": "ES6",
"module": "commonjs" "module": "commonjs",
"esModuleInterop": true
}, },
"exclude": ["node_modules", "test", "src/**/*.test.ts"] "exclude": ["node_modules", "test", "src/**/*.test.ts"]
} }