Compare commits

...

87 Commits

Author SHA1 Message Date
AWS SDKs and Tools bot 00943011d9 chore(main): release 5.1.0 (#1483)
Co-authored-by: Michael Lehmann <lehmanmj@amazon.com>
2025-10-06 10:22:34 -07:00
dependabot[bot] e381dc357a chore(deps-dev): bump @vercel/ncc from 0.38.3 to 0.38.4 (#1500)
Bumps [@vercel/ncc](https://github.com/vercel/ncc) from 0.38.3 to 0.38.4.
- [Release notes](https://github.com/vercel/ncc/releases)
- [Commits](https://github.com/vercel/ncc/compare/0.38.3...0.38.4)

---
updated-dependencies:
- dependency-name: "@vercel/ncc"
  dependency-version: 0.38.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Michael Lehmann <lehmanmj@amazon.com>
2025-10-06 17:19:17 +00:00
dependabot[bot] 031a65bdc1 chore(deps-dev): bump del-cli from 6.0.0 to 7.0.0 (#1497)
Bumps [del-cli](https://github.com/sindresorhus/del-cli) from 6.0.0 to 7.0.0.
- [Release notes](https://github.com/sindresorhus/del-cli/releases)
- [Commits](https://github.com/sindresorhus/del-cli/compare/v6.0.0...v7.0.0)

---
updated-dependencies:
- dependency-name: del-cli
  dependency-version: 7.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Michael Lehmann <lehmanmj@amazon.com>
2025-10-06 17:14:33 +00:00
GitHub Actions 9efe715a4b chore: Update dist 2025-10-06 17:03:50 +00:00
dependabot[bot] 6bbafa679f chore(deps-dev): bump @aws-sdk/credential-provider-env (#1502)
Bumps [@aws-sdk/credential-provider-env](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/credential-provider-env) from 3.894.0 to 3.899.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/credential-provider-env/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.899.0/packages/credential-provider-env)

---
updated-dependencies:
- dependency-name: "@aws-sdk/credential-provider-env"
  dependency-version: 3.899.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-06 17:03:07 +00:00
dependabot[bot] 4c879b4d5d chore(deps-dev): bump @types/node from 24.5.0 to 24.6.0 (#1503)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.5.0 to 24.6.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.6.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Michael Lehmann <lehmanmj@amazon.com>
2025-10-06 17:00:25 +00:00
dependabot[bot] fb52c697f2 chore(deps-dev): bump memfs from 4.39.0 to 4.47.0 (#1504)
Bumps [memfs](https://github.com/streamich/memfs) from 4.39.0 to 4.47.0.
- [Release notes](https://github.com/streamich/memfs/releases)
- [Changelog](https://github.com/streamich/memfs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/streamich/memfs/compare/v4.39.0...v4.47.0)

---
updated-dependencies:
- dependency-name: memfs
  dependency-version: 4.47.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Michael Lehmann <lehmanmj@amazon.com>
2025-10-06 16:58:44 +00:00
GitHub Actions f226b0540e chore: Update dist 2025-09-30 03:14:04 +00:00
dependabot[bot] be2cf0c768 chore(deps): bump @aws-sdk/client-sts from 3.888.0 to 3.899.0 (#1501)
Bumps [@aws-sdk/client-sts](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-sts) from 3.888.0 to 3.899.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-sts/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.899.0/clients/client-sts)

---
updated-dependencies:
- dependency-name: "@aws-sdk/client-sts"
  dependency-version: 3.899.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-30 03:13:23 +00:00
GitHub Actions 0be22f94c3 chore: Update dist 2025-09-23 03:04:11 +00:00
dependabot[bot] 555a8e9ce6 chore(deps-dev): bump @aws-sdk/credential-provider-env (#1495)
Bumps [@aws-sdk/credential-provider-env](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/credential-provider-env) from 3.888.0 to 3.894.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/credential-provider-env/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.894.0/packages/credential-provider-env)

---
updated-dependencies:
- dependency-name: "@aws-sdk/credential-provider-env"
  dependency-version: 3.894.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-23 03:03:30 +00:00
GitHub Actions 6e562ac9ab chore: Update dist 2025-09-16 03:12:34 +00:00
dependabot[bot] 4283504248 chore(deps): bump @aws-sdk/client-sts from 3.883.0 to 3.888.0 (#1492)
Bumps [@aws-sdk/client-sts](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-sts) from 3.883.0 to 3.888.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-sts/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.888.0/clients/client-sts)

---
updated-dependencies:
- dependency-name: "@aws-sdk/client-sts"
  dependency-version: 3.888.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-16 03:11:52 +00:00
GitHub Actions 3146acf819 chore: Update dist 2025-09-16 03:10:19 +00:00
dependabot[bot] 8688f2d5c1 chore(deps-dev): bump @aws-sdk/credential-provider-env (#1490)
Bumps [@aws-sdk/credential-provider-env](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/credential-provider-env) from 3.883.0 to 3.888.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/credential-provider-env/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.888.0/packages/credential-provider-env)

---
updated-dependencies:
- dependency-name: "@aws-sdk/credential-provider-env"
  dependency-version: 3.888.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-16 03:09:38 +00:00
dependabot[bot] 56c08aa702 chore(deps-dev): bump @types/node from 24.3.1 to 24.5.0 (#1494)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.3.1 to 24.5.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.5.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-16 03:07:25 +00:00
dependabot[bot] eda31a964a chore(deps-dev): bump @biomejs/biome from 2.2.3 to 2.2.4 (#1493)
Bumps [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) from 2.2.3 to 2.2.4.
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.2.4/packages/@biomejs/biome)

---
updated-dependencies:
- dependency-name: "@biomejs/biome"
  dependency-version: 2.2.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-16 03:05:07 +00:00
dependabot[bot] 8b7cc57256 chore(deps-dev): bump memfs from 4.38.2 to 4.39.0 (#1491)
Bumps [memfs](https://github.com/streamich/memfs) from 4.38.2 to 4.39.0.
- [Release notes](https://github.com/streamich/memfs/releases)
- [Changelog](https://github.com/streamich/memfs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/streamich/memfs/compare/v4.38.2...v4.39.0)

---
updated-dependencies:
- dependency-name: memfs
  dependency-version: 4.39.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-16 03:03:05 +00:00
GitHub Actions 351d894493 chore: Update dist 2025-09-11 20:33:40 +00:00
Tom Keller 1584b8b0e2 feat: Add global timeout support (#1487) 2025-09-11 13:32:59 -07:00
GitHub Actions b845e0f4f4 chore: Update dist 2025-09-11 19:36:07 +00:00
Tom Keller cea42985ac fix: properly expose getProxyForUrl (introduced in #1482) (#1486)
* chore: use stricter typescript config

* fix: properly expose getProxyForUrl (in #1482)
2025-09-11 12:35:26 -07:00
GitHub Actions 6b19f7ffe6 chore: Update dist 2025-09-11 18:23:03 +00:00
Michał Pawlik 97ef425d73 feat: Improve debug logging in retry logic (#1485) 2025-09-11 11:22:18 -07:00
dependabot[bot] 6bf15574d0 chore(deps): bump vite from 6.3.5 to 7.1.5 (#1484)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.3.5 to 7.1.5.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.1.5/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.1.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-10 02:01:27 +00:00
GitHub Actions 3cb849cb01 chore: Update dist 2025-09-09 23:23:45 +00:00
Tom Keller dde9b22a8e feat: add no-proxy support (#1482) 2025-09-09 16:23:05 -07:00
dependabot[bot] 5ebd15afc6 chore(deps-dev): bump @biomejs/biome from 2.2.2 to 2.2.3 (#1480)
Bumps [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) from 2.2.2 to 2.2.3.
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.2.3/packages/@biomejs/biome)

---
updated-dependencies:
- dependency-name: "@biomejs/biome"
  dependency-version: 2.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-09 03:10:22 +00:00
GitHub Actions c7a2280e36 chore: Update dist 2025-09-09 03:08:42 +00:00
dependabot[bot] 3de82418a6 chore(deps): bump @aws-sdk/client-sts from 3.873.0 to 3.883.0 (#1478)
Bumps [@aws-sdk/client-sts](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-sts) from 3.873.0 to 3.883.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-sts/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.883.0/clients/client-sts)

---
updated-dependencies:
- dependency-name: "@aws-sdk/client-sts"
  dependency-version: 3.883.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-09 03:08:05 +00:00
dependabot[bot] a3143e85cf chore(deps-dev): bump @aws-sdk/credential-provider-env (#1479)
Bumps [@aws-sdk/credential-provider-env](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/credential-provider-env) from 3.879.0 to 3.883.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/credential-provider-env/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.883.0/packages/credential-provider-env)

---
updated-dependencies:
- dependency-name: "@aws-sdk/credential-provider-env"
  dependency-version: 3.883.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-09 03:06:41 +00:00
GitHub Actions 3c23363139 chore: Update dist 2025-09-09 03:05:17 +00:00
dependabot[bot] 44e57d426c chore(deps): bump @smithy/node-http-handler from 4.1.1 to 4.2.0 (#1477)
Bumps [@smithy/node-http-handler](https://github.com/smithy-lang/smithy-typescript/tree/HEAD/packages/node-http-handler) from 4.1.1 to 4.2.0.
- [Release notes](https://github.com/smithy-lang/smithy-typescript/releases)
- [Changelog](https://github.com/smithy-lang/smithy-typescript/blob/main/packages/node-http-handler/CHANGELOG.md)
- [Commits](https://github.com/smithy-lang/smithy-typescript/commits/@smithy/node-http-handler@4.2.0/packages/node-http-handler)

---
updated-dependencies:
- dependency-name: "@smithy/node-http-handler"
  dependency-version: 4.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-09 03:04:26 +00:00
dependabot[bot] b876879204 chore(deps-dev): bump @types/node from 24.3.0 to 24.3.1 (#1475)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.3.0 to 24.3.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.3.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-09 03:02:29 +00:00
Henry Griffiths 8e2d02296b ci: update configure-aws-credentials to v5 (#1470)
BEGIN_COMMIT_OVERRIDE
chore: update configure-aws-credentials to v5 (#1470)
END_COMMIT_OVERRIDE
2025-09-04 16:58:13 -07:00
Henry Griffiths fb3078e4c8 chore: update readme version to v5 (#1469) 2025-09-04 16:56:03 -07:00
Henry Griffiths 0994a359d5 chore: update actions/checkout to v5 (#1471)
Co-authored-by: Tom Keller <1083460+kellertk@users.noreply.github.com>
2025-09-04 23:53:56 +00:00
Tom Keller 1ec058b7a1 chore: revert 163b496 (#1473) 2025-09-04 23:52:28 +00:00
Tom Keller 163b496f8b chore: update AWS role references to use variables (#1472) 2025-09-04 16:46:38 -07:00
Tom Keller f2e9d495b0 chore: remove release-please-action override (#1467) 2025-09-03 13:18:21 -07:00
AWS SDKs and Tools bot a03048d875 chore(main): release 5.0.0 (#1451) 2025-09-03 12:07:05 -07:00
Tom Keller 337f510212 chore: Fix markdown link formatting in README.md (#1466) 2025-09-03 18:41:20 +00:00
Tom Keller f001d79eaa chore: update README with versioning (#1465)
* chore: update README with versioning and license info

* chore: fix typo
2025-09-03 11:35:44 -07:00
GitHub Actions cf5f2acba3 chore: Update dist 2025-09-03 18:25:19 +00:00
dependabot[bot] b394bdd9f0 chore(deps-dev): bump @aws-sdk/credential-provider-env (#1463)
Bumps [@aws-sdk/credential-provider-env](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/credential-provider-env) from 3.876.0 to 3.879.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/credential-provider-env/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.879.0/packages/credential-provider-env)

---
updated-dependencies:
- dependency-name: "@aws-sdk/credential-provider-env"
  dependency-version: 3.879.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-03 18:24:41 +00:00
dependabot[bot] b632c0b5e4 chore(deps-dev): bump memfs from 4.38.1 to 4.38.2 (#1462)
Bumps [memfs](https://github.com/streamich/memfs) from 4.38.1 to 4.38.2.
- [Release notes](https://github.com/streamich/memfs/releases)
- [Changelog](https://github.com/streamich/memfs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/streamich/memfs/compare/v4.38.1...v4.38.2)

---
updated-dependencies:
- dependency-name: memfs
  dependency-version: 4.38.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-03 11:21:36 -07:00
GitHub Actions 978e44aa36 chore: Update dist 2025-09-02 17:38:48 +00:00
Tom Keller c4be498953 feat: support account id allowlist (#1456)
* feat: support account id allowlist

* chore: update readme

---------

Co-authored-by: Michael Lehmann <lehmanmj@amazon.com>
2025-09-02 10:38:09 -07:00
GitHub Actions c5a43c32e1 chore: Update dist 2025-08-30 00:25:47 +00:00
Tom Keller 8c45f6b081 feat: add skip OIDC option (#1458) 2025-08-29 17:25:09 -07:00
Tom Keller a5c87b6a6b chore: update OS matrix in inline-policy for tests-integ-release.yml (#1461)
Removed Windows from the OS matrix in the workflow.
2025-08-29 17:18:16 -07:00
Michael Lehmann 45a41642bb chore: make script inline (#1460)
* add pre-release integ tests

* chore: remove unnecessary sudo and reorganize test files

* chore: inline write token file
2025-08-30 00:11:06 +00:00
Michael Lehmann cb3b499674 chore: redact s3 contents 2025-08-29 16:48:11 -07:00
Michael Lehmann ec8e002276 chore: add pre-release integ tests (#1457)
* add pre-release integ tests

* chore: remove unnecessary sudo and reorganize test files
2025-08-29 16:34:59 -07:00
GitHub Actions 1b2b73eb6a chore: Update dist 2025-08-27 18:21:12 +00:00
dependabot[bot] e30ac4daac chore(deps-dev): bump @aws-sdk/credential-provider-env (#1453)
Bumps [@aws-sdk/credential-provider-env](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/credential-provider-env) from 3.864.0 to 3.873.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/credential-provider-env/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.873.0/packages/credential-provider-env)

---
updated-dependencies:
- dependency-name: "@aws-sdk/credential-provider-env"
  dependency-version: 3.873.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-27 18:20:31 +00:00
GitHub Actions 195dc25ad5 chore: Update dist 2025-08-26 23:30:06 +00:00
dependabot[bot] c284255d3b chore(deps): bump @aws-sdk/client-sts from 3.864.0 to 3.873.0 (#1455)
Bumps [@aws-sdk/client-sts](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-sts) from 3.864.0 to 3.873.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-sts/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.873.0/clients/client-sts)

---
updated-dependencies:
- dependency-name: "@aws-sdk/client-sts"
  dependency-version: 3.873.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-26 23:29:29 +00:00
dependabot[bot] bee3104844 chore(deps-dev): bump @biomejs/biome from 2.2.0 to 2.2.2 (#1454)
Bumps [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) from 2.2.0 to 2.2.2.
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.2.2/packages/@biomejs/biome)

---
updated-dependencies:
- dependency-name: "@biomejs/biome"
  dependency-version: 2.2.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Tom Keller <1083460+kellertk@users.noreply.github.com>
2025-08-26 23:27:07 +00:00
dependabot[bot] 241c954d31 chore(deps-dev): bump memfs from 4.36.3 to 4.38.1 (#1452)
Bumps [memfs](https://github.com/streamich/memfs) from 4.36.3 to 4.38.1.
- [Release notes](https://github.com/streamich/memfs/releases)
- [Changelog](https://github.com/streamich/memfs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/streamich/memfs/compare/v4.36.3...v4.38.1)

---
updated-dependencies:
- dependency-name: memfs
  dependency-version: 4.38.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-26 20:33:49 +00:00
Tom Keller 0eb446ecb2 chore: update last release sha (#1450) 2025-08-20 13:02:28 -07:00
Tom Keller bd1e9e7da1 chore: exclude dist and github from release-processing (#1447) 2025-08-20 11:48:11 -07:00
GitHub Actions 0be2363ca1 chore: Update dist 2025-08-20 18:37:20 +00:00
Tom Keller 74b3e27aa8 chore: cleanup input handling (#1445)
Co-authored-by: Michael Lehmann <lehmanmj@amazon.com>
2025-08-20 11:36:42 -07:00
kellertk df886f22da chore: tests-unit update 2025-08-20 09:48:34 -07:00
GitHub Actions a688da0051 chore: Update dist 2025-08-20 02:51:17 +00:00
dependabot[bot] 4a45167436 chore(deps-dev): bump @biomejs/biome from 2.1.4 to 2.2.0 (#1440)
* chore(deps-dev): bump @biomejs/biome from 2.1.4 to 2.2.0

Bumps [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) from 2.1.4 to 2.2.0.
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.2.0/packages/@biomejs/biome)

---
updated-dependencies:
- dependency-name: "@biomejs/biome"
  dependency-version: 2.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

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

* chore: apply updated linting rules

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: kellertk <kellertk@amazon.com>
2025-08-20 02:50:43 +00:00
dependabot[bot] 0928ae2f74 chore(deps-dev): bump memfs from 4.36.0 to 4.36.3 (#1442)
Bumps [memfs](https://github.com/streamich/memfs) from 4.36.0 to 4.36.3.
- [Release notes](https://github.com/streamich/memfs/releases)
- [Changelog](https://github.com/streamich/memfs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/streamich/memfs/compare/v4.36.0...v4.36.3)

---
updated-dependencies:
- dependency-name: memfs
  dependency-version: 4.36.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-19 22:56:48 +00:00
dependabot[bot] 28c84c0297 chore(deps-dev): bump @types/node from 24.2.1 to 24.3.0 (#1443)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.2.1 to 24.3.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Tom Keller <1083460+kellertk@users.noreply.github.com>
2025-08-19 22:54:30 +00:00
dependabot[bot] 09a74e37ce chore(deps-dev): bump cpy-cli from 5.0.0 to 6.0.0 (#1441)
Bumps [cpy-cli](https://github.com/sindresorhus/cpy-cli) from 5.0.0 to 6.0.0.
- [Release notes](https://github.com/sindresorhus/cpy-cli/releases)
- [Commits](https://github.com/sindresorhus/cpy-cli/compare/v5.0.0...v6.0.0)

---
updated-dependencies:
- dependency-name: cpy-cli
  dependency-version: 6.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-19 13:19:33 +00:00
Tom Keller 3821430d17 chore: update post-release integ test 2025-08-15 15:42:07 -07:00
Tom Keller 3df3b9e987 use correct ref 2025-08-15 15:29:45 -07:00
Tom Keller a91a6303b8 chore: create tests-integ.yml 2025-08-15 15:29:45 -07:00
dependabot[bot] 209f2a4450 chore(deps-dev): bump @types/node from 24.2.0 to 24.2.1 (#1430)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.2.0 to 24.2.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.2.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 18:10:40 +00:00
dependabot[bot] 92fa2639a8 chore(deps-dev): bump @biomejs/biome from 2.1.3 to 2.1.4 (#1433)
Bumps [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) from 2.1.3 to 2.1.4.
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.1.4/packages/@biomejs/biome)

---
updated-dependencies:
- dependency-name: "@biomejs/biome"
  dependency-version: 2.1.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 18:06:49 +00:00
GitHub Actions 5505db6539 chore: Update dist 2025-08-12 17:57:14 +00:00
dependabot[bot] 51e8c081a1 chore(deps): bump @aws-sdk/client-sts from 3.859.0 to 3.864.0 (#1431)
Bumps [@aws-sdk/client-sts](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-sts) from 3.859.0 to 3.864.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-sts/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.864.0/clients/client-sts)

---
updated-dependencies:
- dependency-name: "@aws-sdk/client-sts"
  dependency-version: 3.864.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 17:56:35 +00:00
GitHub Actions 00dc4f2d3d chore: Update dist 2025-08-12 17:53:48 +00:00
dependabot[bot] 24a1539a9c chore(deps-dev): bump @aws-sdk/credential-provider-env (#1435)
Bumps [@aws-sdk/credential-provider-env](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/credential-provider-env) from 3.858.0 to 3.864.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/credential-provider-env/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.864.0/packages/credential-provider-env)

---
updated-dependencies:
- dependency-name: "@aws-sdk/credential-provider-env"
  dependency-version: 3.864.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Tom Keller <1083460+kellertk@users.noreply.github.com>
2025-08-12 17:53:08 +00:00
dependabot[bot] 4cc620671e chore(deps): bump @smithy/node-http-handler from 4.1.0 to 4.1.1 (#1429)
Bumps [@smithy/node-http-handler](https://github.com/smithy-lang/smithy-typescript/tree/HEAD/packages/node-http-handler) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/smithy-lang/smithy-typescript/releases)
- [Changelog](https://github.com/smithy-lang/smithy-typescript/blob/main/packages/node-http-handler/CHANGELOG.md)
- [Commits](https://github.com/smithy-lang/smithy-typescript/commits/@smithy/node-http-handler@4.1.1/packages/node-http-handler)

---
updated-dependencies:
- dependency-name: "@smithy/node-http-handler"
  dependency-version: 4.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 11:02:38 +00:00
dependabot[bot] aa1f74b81b chore(deps-dev): bump @types/node from 24.1.0 to 24.2.0 (#1427)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.1.0 to 24.2.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Tom Keller <1083460+kellertk@users.noreply.github.com>
2025-08-05 15:23:01 +00:00
dependabot[bot] 2de20cdfbc chore(deps-dev): bump memfs from 4.35.0 to 4.36.0 (#1426)
Bumps [memfs](https://github.com/streamich/memfs) from 4.35.0 to 4.36.0.
- [Release notes](https://github.com/streamich/memfs/releases)
- [Changelog](https://github.com/streamich/memfs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/streamich/memfs/compare/v4.35.0...v4.36.0)

---
updated-dependencies:
- dependency-name: memfs
  dependency-version: 4.36.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-05 09:52:29 +00:00
AWS SDKs and Tools bot 7474bc4690 chore(main): release 4.3.1 2025-08-04 16:23:36 -07:00
Tom Keller be2e7ad815 fix: update readme to 4.3.1 (#1424)
This is a fix instead of a chore to force a 4.3.1 tag

Release-as: 4.3.1
2025-08-04 23:17:49 +00:00
Michael Lehmann 4a9906ba73 Merge pull request #1422 from aws-actions/lehmanmj-patch-2
chore: Update README.md
2025-08-04 13:54:52 -07:00
Michael Lehmann 83a7f06197 Update README.md
update readme with latest version
2025-08-04 13:52:04 -07:00
Tom Keller b8b4fdbcd4 Update CHANGELOG.md 2025-08-04 13:47:32 -07:00
33 changed files with 51353 additions and 17860 deletions
+6
View File
@@ -0,0 +1,6 @@
Port 9999
Listen 127.0.0.1
Timeout 600
Allow 127.0.0.1
LogFile "/home/runner/work/configure-aws-credentials/configure-aws-credentials/integ_proxy_log.txt"
LogLevel Connect
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
uses: aws-actions/configure-aws-credentials@v5
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.SECRETS_AWS_PACKAGING_ROLE_TO_ASSUME }}
+2 -2
View File
@@ -15,10 +15,10 @@ jobs:
- name: Get Metadata
id: dependabot-metadata
uses: dependabot/fetch-metadata@v2
- uses: actions/checkout@v4
- uses: actions/checkout@v5
name: Clone repo
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
uses: aws-actions/configure-aws-credentials@v5
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.CONFIGUREAWSCREDENTIALSPACKAGEROLEARN }}
+2 -2
View File
@@ -17,7 +17,7 @@ jobs:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
ref: ${{ github.ref_name }}
@@ -28,7 +28,7 @@ jobs:
npm test
npm run package
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
uses: aws-actions/configure-aws-credentials@v5
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.SECRETS_AWS_PACKAGING_ROLE_TO_ASSUME }}
+2 -2
View File
@@ -15,12 +15,12 @@
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
uses: aws-actions/configure-aws-credentials@v5
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.SECRETS_AWS_PACKAGING_ROLE_TO_ASSUME }}
+32
View File
@@ -0,0 +1,32 @@
name: Run post-release integration test
on:
push:
branches:
- main
paths:
- 'dist/**'
workflow_dispatch:
jobs:
package_and_test:
name: Package dist files
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
persist-credentials: false
- name: Integation tests
uses: ./
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.CAWSC_integ_role }}
role-session-name: IntegTestCAWSC
- name: Get caller identity
run: |
aws sts get-caller-identity
+202
View File
@@ -0,0 +1,202 @@
name: Run pre-release integ tests
on:
pull_request_target:
permissions:
contents: read
jobs:
oidc:
if: ${{ github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials' }}
permissions:
id-token: write
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
name: OIDC login test
steps:
- name: checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
persist-credentials: false
- name: Configure AWS credentials
uses: ./
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.OIDC_integ_role }}
- name: Get Caller Identity
run: |
aws sts get-caller-identity
#can cut this test out if it's not necessary
static_assumeRole:
if: ${{ github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials' }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
name: Static IAM creds test
steps:
- name: checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
persist-credentials: false
- name: Configure AWS credentials
uses: ./
with:
aws-region: us-west-2
aws-access-key-id: ${{ secrets.STATIC_ak_id }}
aws-secret-access-key: ${{ secrets.STATIC_secret_ak }}
role-to-assume: ${{ secrets.STATIC_role }}
- name: Get Caller Identity
run: |
aws sts get-caller-identity
role_chaining:
if: ${{ github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials' }}
permissions:
id-token: write
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
name: Existing Creds + Role Chaining test
steps:
- name: checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
persist-credentials: false
- name: Configure AWS credentials
uses: ./
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.ROLE_chaining_1 }}
- name: Get Caller Identity
run: |
aws sts get-caller-identity
- name: assume second role
uses: ./
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.ROLE_chaining_2 }}
role-chaining: true
- name: get caller identity
run: |
aws sts get-caller-identity
inline_policy:
if: ${{ github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials' }}
permissions:
id-token: write
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
name: Inline Policy Test
steps:
- name: checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
persist-credentials: false
- name: get creds w scoped down policy
uses: ./
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.INLINE_policy_role }}
inline-session-policy: '{"Version":"2012-10-17","Statement":[{"Sid":"Stmt1","Effect":"Allow","Action":"s3:ListAllMyBuckets","Resource":"*"}]}'
#NOTE: This step should succeed. The role should have permission only to list all buckets.
- name: list buckets
run: aws s3 ls > /dev/null
#NOTE: This step should fail. we don't want the role to have permission to see the bucket contents.
- name: try to list bucket contents
id: bucketContentsStep
continue-on-error: true
run: aws s3 ls s3://cawsc-integ-tests-bucket > /dev/null
#But the test fails if we could list the bucket contents.
- name: fail if we can list bucket contents
if: steps.bucketContentsStep.outcome == 'success'
run: exit 1
http-proxy:
if: ${{ github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials' }}
permissions:
id-token: write
runs-on: ubuntu-latest
name: HTTP Proxy Test
steps:
- name: checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
persist-credentials: false
- name: install tinyproxy
run: |
sudo apt-get update
sudo apt-get -y install tinyproxy
- name: start tinyproxy
run: tinyproxy -c .github/integ_tests/tinyproxy.conf
- name: Configure AWS credentials
continue-on-error: true
uses: ./
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.OIDC_integ_role }}
http-proxy: http://127.0.0.1:9999
retry-max-attempts: 4
- name: checkout logs
run: cat integ_proxy_log.txt
- name: check logs to see if successful call
run: grep -q "Request" integ_proxy_log.txt && echo "PROXY_CALL_LOGGED=1" >> $GITHUB_ENV || echo "PROXY_CALL_LOGGED=0" >> $GITHUB_ENV
- name: fail job if bad call
if: ${{ env.PROXY_CALL_LOGGED != 1 }}
run: exit 1
token-file:
if: ${{ github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials' }}
permissions:
id-token: write
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
name: Token File Test
steps:
- name: checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
persist-credentials: false
- name: fetch token and write to file
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
async function getIDTokenAction() {
const id_token = await core.getIDToken("sts.amazonaws.com");
return id_token;
}
const idToken = await getIDTokenAction();
fs.writeFileSync(".github/integ_tests/integ_token.txt", idToken, (err) => {
if (err) throw err;
});
- name: get creds with that file
uses: ./
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.OIDC_integ_role }}
web-identity-token-file: .github/integ_tests/integ_token.txt
retry-max-attempts: 4
- name: check creds
run: aws sts get-caller-identity
+6 -4
View File
@@ -2,6 +2,8 @@ on:
[pull_request]
name: Run unit tests
permissions:
contents: read
jobs:
unit-test:
@@ -14,13 +16,13 @@ jobs:
timeout-minutes: 5
steps:
- name: "Checkout repository"
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: "Setup node"
uses: actions/setup-node@v4
uses: actions/setup-node@v4.4.0
with:
node-version: 20
- name: "Install dependencies"
uses: bahmutov/npm-install@v1
run: npm ci
- name: "Run tests"
run: npm run test --if-present
lint:
@@ -29,7 +31,7 @@ jobs:
timeout-minutes: 5
steps:
- name: "Checkout repostiory"
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: "Setup node"
uses: actions/setup-node@v4
with:
+1 -1
View File
@@ -1,5 +1,5 @@
{
".release-please-manifest.json": "4.0.2",
"package.json": "4.0.2",
".": "4.3.0"
".": "5.1.0"
}
+32 -4
View File
@@ -2,17 +2,39 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [4.3.0](https://github.com/aws-actions/configure-aws-credentials/compare/v4.3.0...v4.3.0) (2025-08-04)
## [5.1.0](https://github.com/aws-actions/configure-aws-credentials/compare/v5.0.0...v5.1.0) (2025-10-06)
### Features
* Add global timeout support ([#1487](https://github.com/aws-actions/configure-aws-credentials/issues/1487)) ([1584b8b](https://github.com/aws-actions/configure-aws-credentials/commit/1584b8b0e2062557287c28fbe9b8920df434e866))
* add no-proxy support ([#1482](https://github.com/aws-actions/configure-aws-credentials/issues/1482)) ([dde9b22](https://github.com/aws-actions/configure-aws-credentials/commit/dde9b22a8e889a0821997a21a2c5a38020ee8de3))
* Improve debug logging in retry logic ([#1485](https://github.com/aws-actions/configure-aws-credentials/issues/1485)) ([97ef425](https://github.com/aws-actions/configure-aws-credentials/commit/97ef425d73aa532439f54f90d0e83101a186c5a6))
### Bug Fixes
* properly set proxy environment variable ([cbea708](https://github.com/aws-actions/configure-aws-credentials/commit/cbea70821e4ab985ad3be0e5a93390523e257cde))
* properly expose getProxyForUrl (introduced in [#1482](https://github.com/aws-actions/configure-aws-credentials/issues/1482)) ([#1486](https://github.com/aws-actions/configure-aws-credentials/issues/1486)) ([cea4298](https://github.com/aws-actions/configure-aws-credentials/commit/cea42985ac88b42678fbc84c18066a7f07f05176))
## [5.0.0](https://github.com/aws-actions/configure-aws-credentials/compare/v4.3.1...v5.0.0) (2025-09-03)
### Miscellaneous Chores
### ⚠ BREAKING CHANGES
* release 4.3.0 ([3f7c218](https://github.com/aws-actions/configure-aws-credentials/commit/3f7c2187213bafaa1ea60a850b27082cbf55dda0))
* Cleanup input handling. Changes invalid boolean input behavior (see #1445)
### Features
* add skip OIDC option ([#1458](https://github.com/aws-actions/configure-aws-credentials/issues/1458)) ([8c45f6b](https://github.com/aws-actions/configure-aws-credentials/commit/8c45f6b08196feb86cfdbe431541d5571d9ab2c2))
* Cleanup input handling. Changes invalid boolean input behavior (see [#1445](https://github.com/aws-actions/configure-aws-credentials/issues/1445)) ([74b3e27](https://github.com/aws-actions/configure-aws-credentials/commit/74b3e27aa80db064b5bb8c04b22fc607e817acf7))
* support account id allowlist ([#1456](https://github.com/aws-actions/configure-aws-credentials/issues/1456)) ([c4be498](https://github.com/aws-actions/configure-aws-credentials/commit/c4be498953fc1da2707a50ce4b761a53af3d02af))
## [4.3.1](https://github.com/aws-actions/configure-aws-credentials/compare/v4.3.0...v4.3.1) (2025-08-04)
### Bug Fixes
* update readme to 4.3.1 ([#1424](https://github.com/aws-actions/configure-aws-credentials/issues/1424)) ([be2e7ad](https://github.com/aws-actions/configure-aws-credentials/commit/be2e7ad815e27b890489a89ce2717b0f9e26b56e))
## [4.3.0](https://github.com/aws-actions/configure-aws-credentials/compare/v4.2.1...v4.3.0) (2025-08-04)
@@ -27,6 +49,12 @@ All notable changes to this project will be documented in this file. See [standa
* **docs:** readme samples versioning ([5b3c895](https://github.com/aws-actions/configure-aws-credentials/commit/5b3c89504689ea1ea2b6000b23a6a2aac463662a))
* the wrong example region for China partition in README ([37fe9a7](https://github.com/aws-actions/configure-aws-credentials/commit/37fe9a740bcb30ee8cccd96feb90666c937311f2))
* properly set proxy environment variable ([cbea708](https://github.com/aws-actions/configure-aws-credentials/commit/cbea70821e4ab985ad3be0e5a93390523e257cde))
### Miscellaneous Chores
* release 4.3.0 ([3f7c218](https://github.com/aws-actions/configure-aws-credentials/commit/3f7c2187213bafaa1ea60a850b27082cbf55dda0))
## [4.2.1](https://github.com/aws-actions/configure-aws-credentials/compare/v4.2.0...v4.2.1) (2025-05-14)
+23 -13
View File
@@ -143,13 +143,16 @@ See [action.yml](./action.yml) for more detail.
| role-skip-session-tagging | Skips session tagging if set. | No |
| inline-session-policy | You may further restrict the assumed role policy by defining an inline policy here. | No |
| managed-session-policies | You may further restrict the assumed role policy by specifying a managed policy here. | No |
| output-credentials | When set, outputs fetched credentials as action step output. (Outputs aws-access-key-id, aws-secret-access-key, aws-session-token, aws-account-id, and aws-expiration). Defaults to false. | No |
| output-credentials | When set, outputs fetched credentials as action step output. (Outputs aws-access-key-id, aws-secret-access-key, aws-session-token, aws-account-id, authenticated-arn, and aws-expiration). Defaults to false. | No |
| output-env-credentials | When set, outputs fetched credentials as environment variables (AWS_REGION, AWS_DEFAULT_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN). Defaults to true. Set to false if you need to avoid setting/changing env variables. You'd probably want to use output-credentials if you disable this. (NOTE: Setting to false will prevent the aws-account-id from being exported as a step output). | No |
| unset-current-credentials | When set, attempts to unset any existing credentials in your action runner. | No |
| disable-retry | Disabled retry/backoff logic for assume role calls. By default, retries are enabled. | No |
| retry-max-attempts | Limits the number of retry attempts before giving up. Defaults to 12. | No |
| special-characters-workaround | Uncommonly, some environments cannot tolerate special characters in a secret key. This option will retry fetching credentials until the secret access key does not contain special characters. This option overrides disable-retry and retry-max-attempts. | No |
| use-existing-credentials | When set, the action will check if existing credentials are valid and exit if they are. Defaults to false. | No |
| allowed-account-ids | A comma-delimited list of expected AWS account IDs. The action will fail if we receive credentials for the wrong account. | No |
| force-skip-oidc | When set, the action will skip using GitHub OIDC provider even if the id-token permission is set. | No |
| action-timeout-s | Global timeout for the action in seconds. If set to a value greater than 0, the action will fail if it takes longer than this time to complete. | No |
</details>
#### Adjust the retry mechanism
@@ -178,7 +181,7 @@ this action will always consider the `HTTP_PROXY` environment variable.
Manually configured proxy:
```yaml
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
aws-region: us-east-2
role-to-assume: my-github-actions-role
@@ -249,13 +252,13 @@ line.
<summary>Inline session policy examples</summary>
```yaml
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
inline-session-policy: '{"Version":"2012-10-17","Statement":[{"Sid":"Stmt1","Effect":"Allow","Action":"s3:List*","Resource":"*"}]}'
```
Or we can have a nicely formatted JSON as well:
```yaml
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
inline-session-policy: >-
{
@@ -281,13 +284,13 @@ the role.
<summary>Managed session policy examples</summary>
```yaml
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
managed-session-policies: arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
```
And we can pass multiple managed policies likes this:
```yaml
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
managed-session-policies: |
arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
@@ -325,7 +328,7 @@ You can specify the audience through the `audience` input:
```yaml
- name: Configure AWS Credentials for China region audience
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
audience: sts.amazonaws.com.cn
aws-region: cn-northwest-1
@@ -399,7 +402,7 @@ Examples
### AssumeRoleWithWebIdentity
```yaml
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
aws-region: us-east-2
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
@@ -413,13 +416,13 @@ environment variable and use it to assume the role
### AssumeRole with role previously assumed by action in same workflow
```yaml
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
aws-region: us-east-2
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
role-session-name: MySessionName
- name: Configure other AWS Credentials
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
aws-region: us-east-2
role-to-assume: arn:aws:iam::987654321000:role/my-second-role
@@ -434,7 +437,7 @@ role, `arn:aws:iam::987654321000:role/my-second-role`.
### AssumeRole with static IAM credentials in repository secrets
```yaml
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -453,7 +456,7 @@ name, like `role-to-assume: my-github-actions-role`.
```yaml
- name: Configure AWS Credentials 1
id: creds
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
aws-region: us-east-2
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
@@ -462,7 +465,7 @@ name, like `role-to-assume: my-github-actions-role`.
run: |
aws sts get-caller-identity
- name: Configure AWS Credentials 2
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
aws-region: us-east-2
aws-access-key-id: ${{ steps.creds.outputs.aws-access-key-id }}
@@ -478,6 +481,13 @@ This example shows that you can reference the fetched credentials as outputs if
the `aws-session-token` input in a situation where session tokens are fetched
and passed to this action.
Versioning
----------
Starting with version 5.0.0, this action uses semantic-style release tags and
[immutable releases](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/immutable-releases).
A floating version tag (vN) is also provided for convenience: this tag will
move to the latest major version (vN -> vN.2.1, vM -> vM.0.0, etc.).
License
-------
This code is made available under the MIT license.
+14
View File
@@ -37,6 +37,9 @@ inputs:
http-proxy:
description: Proxy to use for the AWS SDK agent
required: false
no-proxy:
description: Hosts to skip for the proxy configuration
required: false
mask-aws-account-id:
description: Whether to mask the AWS account ID for these credentials as a secret value. By default the account ID will not be masked
required: false
@@ -78,7 +81,18 @@ inputs:
description: Some environments do not support special characters in AWS_SECRET_ACCESS_KEY. This option will retry fetching credentials until the secret access key does not contain special characters. This option overrides disable-retry and retry-max-attempts. This option is disabled by default
required: false
use-existing-credentials:
required: false
description: When enabled, this option will check if there are already valid credentials in the environment. If there are, new credentials will not be fetched. If there are not, the action will run as normal.
allowed-account-ids:
required: false
description: An option comma-delimited list of expected AWS account IDs. The action will fail if we receive credentials for the wrong account.
force-skip-oidc:
required: false
description: When enabled, this option will skip using GitHub OIDC provider even if the id-token permission is set. This is sometimes useful when using IAM instance credentials.
action-timeout-s:
required: false
description: A global timeout in seconds for the action. When the timeout is reached, the action immediately exits. The default is to run without a timeout.
outputs:
aws-account-id:
description: The AWS account ID for the provided credentials
+4
View File
@@ -12,6 +12,10 @@
"performance": {
"noDelete": "off"
},
"correctness": {
// Specifying a radix disables interpretation of 0x as a number (needed for backwards compat)
"useParseIntRadix": "off"
},
"complexity": {
"noExtraBooleanCast": "off"
}
Generated Vendored
+224
View File
@@ -0,0 +1,224 @@
"use strict";
exports.id = 579;
exports.ids = [579];
exports.modules = {
/***/ 6579:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
var schema = __webpack_require__(6890);
var utilUtf8 = __webpack_require__(1577);
class EventStreamSerde {
marshaller;
serializer;
deserializer;
serdeContext;
defaultContentType;
constructor({ marshaller, serializer, deserializer, serdeContext, defaultContentType, }) {
this.marshaller = marshaller;
this.serializer = serializer;
this.deserializer = deserializer;
this.serdeContext = serdeContext;
this.defaultContentType = defaultContentType;
}
async serializeEventStream({ eventStream, requestSchema, initialRequest, }) {
const marshaller = this.marshaller;
const eventStreamMember = requestSchema.getEventStreamMember();
const unionSchema = requestSchema.getMemberSchema(eventStreamMember);
unionSchema.getMemberSchemas();
const serializer = this.serializer;
const defaultContentType = this.defaultContentType;
const initialRequestMarker = Symbol("initialRequestMarker");
const eventStreamIterable = {
async *[Symbol.asyncIterator]() {
if (initialRequest) {
const headers = {
":event-type": { type: "string", value: "initial-request" },
":message-type": { type: "string", value: "event" },
":content-type": { type: "string", value: defaultContentType },
};
serializer.write(requestSchema, initialRequest);
const body = serializer.flush();
yield {
[initialRequestMarker]: true,
headers,
body,
};
}
for await (const page of eventStream) {
yield page;
}
},
};
return marshaller.serialize(eventStreamIterable, (event) => {
if (event[initialRequestMarker]) {
return {
headers: event.headers,
body: event.body,
};
}
const unionMember = Object.keys(event).find((key) => {
return key !== "__type";
}) ?? "";
const { additionalHeaders, body, eventType, explicitPayloadContentType } = this.writeEventBody(unionMember, unionSchema, event);
const headers = {
":event-type": { type: "string", value: eventType },
":message-type": { type: "string", value: "event" },
":content-type": { type: "string", value: explicitPayloadContentType ?? defaultContentType },
...additionalHeaders,
};
return {
headers,
body,
};
});
}
async deserializeEventStream({ response, responseSchema, initialResponseContainer, }) {
const marshaller = this.marshaller;
const eventStreamMember = responseSchema.getEventStreamMember();
const unionSchema = responseSchema.getMemberSchema(eventStreamMember);
const memberSchemas = unionSchema.getMemberSchemas();
const initialResponseMarker = Symbol("initialResponseMarker");
const asyncIterable = marshaller.deserialize(response.body, async (event) => {
const unionMember = Object.keys(event).find((key) => {
return key !== "__type";
}) ?? "";
if (unionMember === "initial-response") {
const dataObject = await this.deserializer.read(responseSchema, event[unionMember].body);
delete dataObject[eventStreamMember];
return {
[initialResponseMarker]: true,
...dataObject,
};
}
else if (unionMember in memberSchemas) {
const eventStreamSchema = memberSchemas[unionMember];
return {
[unionMember]: await this.deserializer.read(eventStreamSchema, event[unionMember].body),
};
}
else {
return {
$unknown: event,
};
}
});
const asyncIterator = asyncIterable[Symbol.asyncIterator]();
const firstEvent = await asyncIterator.next();
if (firstEvent.done) {
return asyncIterable;
}
if (firstEvent.value?.[initialResponseMarker]) {
if (!responseSchema) {
throw new Error("@smithy::core/protocols - initial-response event encountered in event stream but no response schema given.");
}
for (const [key, value] of Object.entries(firstEvent.value)) {
initialResponseContainer[key] = value;
}
}
return {
async *[Symbol.asyncIterator]() {
if (!firstEvent?.value?.[initialResponseMarker]) {
yield firstEvent.value;
}
while (true) {
const { done, value } = await asyncIterator.next();
if (done) {
break;
}
yield value;
}
},
};
}
writeEventBody(unionMember, unionSchema, event) {
const serializer = this.serializer;
let eventType = unionMember;
let explicitPayloadMember = null;
let explicitPayloadContentType;
const isKnownSchema = unionSchema.hasMemberSchema(unionMember);
const additionalHeaders = {};
if (!isKnownSchema) {
const [type, value] = event[unionMember];
eventType = type;
serializer.write(schema.SCHEMA.DOCUMENT, value);
}
else {
const eventSchema = unionSchema.getMemberSchema(unionMember);
if (eventSchema.isStructSchema()) {
for (const [memberName, memberSchema] of eventSchema.structIterator()) {
const { eventHeader, eventPayload } = memberSchema.getMergedTraits();
if (eventPayload) {
explicitPayloadMember = memberName;
break;
}
else if (eventHeader) {
const value = event[unionMember][memberName];
let type = "binary";
if (memberSchema.isNumericSchema()) {
if ((-2) ** 31 <= value && value <= 2 ** 31 - 1) {
type = "integer";
}
else {
type = "long";
}
}
else if (memberSchema.isTimestampSchema()) {
type = "timestamp";
}
else if (memberSchema.isStringSchema()) {
type = "string";
}
else if (memberSchema.isBooleanSchema()) {
type = "boolean";
}
if (value != null) {
additionalHeaders[memberName] = {
type,
value,
};
delete event[unionMember][memberName];
}
}
}
if (explicitPayloadMember !== null) {
const payloadSchema = eventSchema.getMemberSchema(explicitPayloadMember);
if (payloadSchema.isBlobSchema()) {
explicitPayloadContentType = "application/octet-stream";
}
else if (payloadSchema.isStringSchema()) {
explicitPayloadContentType = "text/plain";
}
serializer.write(payloadSchema, event[unionMember][explicitPayloadMember]);
}
else {
serializer.write(eventSchema, event[unionMember]);
}
}
else {
throw new Error("@smithy/core/event-streams - non-struct member not supported in event stream union.");
}
}
const messageSerialization = serializer.flush();
const body = typeof messageSerialization === "string"
? (this.serdeContext?.utf8Decoder ?? utilUtf8.fromUtf8)(messageSerialization)
: messageSerialization;
return {
body,
eventType,
explicitPayloadContentType,
additionalHeaders,
};
}
}
exports.EventStreamSerde = EventStreamSerde;
/***/ })
};
;
Generated Vendored
+224
View File
@@ -0,0 +1,224 @@
"use strict";
exports.id = 579;
exports.ids = [579];
exports.modules = {
/***/ 6579:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
var schema = __webpack_require__(6890);
var utilUtf8 = __webpack_require__(1577);
class EventStreamSerde {
marshaller;
serializer;
deserializer;
serdeContext;
defaultContentType;
constructor({ marshaller, serializer, deserializer, serdeContext, defaultContentType, }) {
this.marshaller = marshaller;
this.serializer = serializer;
this.deserializer = deserializer;
this.serdeContext = serdeContext;
this.defaultContentType = defaultContentType;
}
async serializeEventStream({ eventStream, requestSchema, initialRequest, }) {
const marshaller = this.marshaller;
const eventStreamMember = requestSchema.getEventStreamMember();
const unionSchema = requestSchema.getMemberSchema(eventStreamMember);
unionSchema.getMemberSchemas();
const serializer = this.serializer;
const defaultContentType = this.defaultContentType;
const initialRequestMarker = Symbol("initialRequestMarker");
const eventStreamIterable = {
async *[Symbol.asyncIterator]() {
if (initialRequest) {
const headers = {
":event-type": { type: "string", value: "initial-request" },
":message-type": { type: "string", value: "event" },
":content-type": { type: "string", value: defaultContentType },
};
serializer.write(requestSchema, initialRequest);
const body = serializer.flush();
yield {
[initialRequestMarker]: true,
headers,
body,
};
}
for await (const page of eventStream) {
yield page;
}
},
};
return marshaller.serialize(eventStreamIterable, (event) => {
if (event[initialRequestMarker]) {
return {
headers: event.headers,
body: event.body,
};
}
const unionMember = Object.keys(event).find((key) => {
return key !== "__type";
}) ?? "";
const { additionalHeaders, body, eventType, explicitPayloadContentType } = this.writeEventBody(unionMember, unionSchema, event);
const headers = {
":event-type": { type: "string", value: eventType },
":message-type": { type: "string", value: "event" },
":content-type": { type: "string", value: explicitPayloadContentType ?? defaultContentType },
...additionalHeaders,
};
return {
headers,
body,
};
});
}
async deserializeEventStream({ response, responseSchema, initialResponseContainer, }) {
const marshaller = this.marshaller;
const eventStreamMember = responseSchema.getEventStreamMember();
const unionSchema = responseSchema.getMemberSchema(eventStreamMember);
const memberSchemas = unionSchema.getMemberSchemas();
const initialResponseMarker = Symbol("initialResponseMarker");
const asyncIterable = marshaller.deserialize(response.body, async (event) => {
const unionMember = Object.keys(event).find((key) => {
return key !== "__type";
}) ?? "";
if (unionMember === "initial-response") {
const dataObject = await this.deserializer.read(responseSchema, event[unionMember].body);
delete dataObject[eventStreamMember];
return {
[initialResponseMarker]: true,
...dataObject,
};
}
else if (unionMember in memberSchemas) {
const eventStreamSchema = memberSchemas[unionMember];
return {
[unionMember]: await this.deserializer.read(eventStreamSchema, event[unionMember].body),
};
}
else {
return {
$unknown: event,
};
}
});
const asyncIterator = asyncIterable[Symbol.asyncIterator]();
const firstEvent = await asyncIterator.next();
if (firstEvent.done) {
return asyncIterable;
}
if (firstEvent.value?.[initialResponseMarker]) {
if (!responseSchema) {
throw new Error("@smithy::core/protocols - initial-response event encountered in event stream but no response schema given.");
}
for (const [key, value] of Object.entries(firstEvent.value)) {
initialResponseContainer[key] = value;
}
}
return {
async *[Symbol.asyncIterator]() {
if (!firstEvent?.value?.[initialResponseMarker]) {
yield firstEvent.value;
}
while (true) {
const { done, value } = await asyncIterator.next();
if (done) {
break;
}
yield value;
}
},
};
}
writeEventBody(unionMember, unionSchema, event) {
const serializer = this.serializer;
let eventType = unionMember;
let explicitPayloadMember = null;
let explicitPayloadContentType;
const isKnownSchema = unionSchema.hasMemberSchema(unionMember);
const additionalHeaders = {};
if (!isKnownSchema) {
const [type, value] = event[unionMember];
eventType = type;
serializer.write(schema.SCHEMA.DOCUMENT, value);
}
else {
const eventSchema = unionSchema.getMemberSchema(unionMember);
if (eventSchema.isStructSchema()) {
for (const [memberName, memberSchema] of eventSchema.structIterator()) {
const { eventHeader, eventPayload } = memberSchema.getMergedTraits();
if (eventPayload) {
explicitPayloadMember = memberName;
break;
}
else if (eventHeader) {
const value = event[unionMember][memberName];
let type = "binary";
if (memberSchema.isNumericSchema()) {
if ((-2) ** 31 <= value && value <= 2 ** 31 - 1) {
type = "integer";
}
else {
type = "long";
}
}
else if (memberSchema.isTimestampSchema()) {
type = "timestamp";
}
else if (memberSchema.isStringSchema()) {
type = "string";
}
else if (memberSchema.isBooleanSchema()) {
type = "boolean";
}
if (value != null) {
additionalHeaders[memberName] = {
type,
value,
};
delete event[unionMember][memberName];
}
}
}
if (explicitPayloadMember !== null) {
const payloadSchema = eventSchema.getMemberSchema(explicitPayloadMember);
if (payloadSchema.isBlobSchema()) {
explicitPayloadContentType = "application/octet-stream";
}
else if (payloadSchema.isStringSchema()) {
explicitPayloadContentType = "text/plain";
}
serializer.write(payloadSchema, event[unionMember][explicitPayloadMember]);
}
else {
serializer.write(eventSchema, event[unionMember]);
}
}
else {
throw new Error("@smithy/core/event-streams - non-struct member not supported in event stream union.");
}
}
const messageSerialization = serializer.flush();
const body = typeof messageSerialization === "string"
? (this.serdeContext?.utf8Decoder ?? utilUtf8.fromUtf8)(messageSerialization)
: messageSerialization;
return {
body,
eventType,
explicitPayloadContentType,
additionalHeaders,
};
}
}
exports.EventStreamSerde = EventStreamSerde;
/***/ })
};
;
Generated Vendored
+8203 -8373
View File
File diff suppressed because it is too large Load Diff
Generated Vendored
+40449 -8435
View File
File diff suppressed because one or more lines are too long
@@ -6,7 +6,7 @@ jobs:
sast-guard:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: grolston/guard-action@main
with:
data_directory: './cloudformation/' ## change to your template directory
+2 -2
View File
@@ -18,9 +18,9 @@ jobs:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
uses: aws-actions/configure-aws-credentials@v5
with:
aws-region: us-east-1
## the following creates an ARN based on the values entered into github secrets
-31
View File
@@ -1,31 +0,0 @@
/** @type {import('jest').Config} */
const config = {
verbose: true,
transform: {
'^.+\\.m?[tj]sx?$': ['ts-jest'],
},
testMatch: [
'<rootDir>/src/**/__tests__/**/*.ts?(x)',
'<rootDir>/(test|src)/**/*(*.)@(spec|test).ts?(x)',
'<rootDir>/test/**/*.(test|spec).(js|jsx|ts|tsx)',
],
clearMocks: true,
collectCoverage: true,
coverageReporters: ['json', 'lcov', 'clover', 'cobertura', 'text'],
coverageDirectory: 'coverage',
coveragePathIgnorePatterns: ['/node_modules/'],
testPathIgnorePatterns: ['/node_modules/'],
watchPathIgnorePatterns: ['/node_modules/'],
reporters: [
'default',
[
'jest-junit',
{
outputDirectory: 'test-reports',
},
],
],
preset: 'ts-jest/presets/default-legacy',
};
module.exports = config;
+1091 -877
View File
File diff suppressed because it is too large Load Diff
+11 -11
View File
@@ -1,7 +1,7 @@
{
"name": "configure-aws-credentials",
"description": "A GitHub Action to configure AWS credentials",
"version": "4.3.0",
"version": "5.1.0",
"scripts": {
"build": "tsc",
"lint": "biome check --error-on-warnings ./src",
@@ -16,26 +16,26 @@
"organization": true
},
"devDependencies": {
"@aws-sdk/credential-provider-env": "^3.858.0",
"@biomejs/biome": "2.1.3",
"@aws-sdk/credential-provider-env": "^3.901.0",
"@biomejs/biome": "2.2.4",
"@smithy/property-provider": "^4.0.3",
"@types/node": "^24.1.0",
"@vercel/ncc": "^0.38.3",
"@types/node": "^24.6.0",
"@vercel/ncc": "^0.38.4",
"@vitest/coverage-v8": "^3.2.4",
"aws-sdk-client-mock": "^4.1.0",
"cpy-cli": "^5.0.0",
"del-cli": "^6.0.0",
"cpy-cli": "^6.0.0",
"del-cli": "^7.0.0",
"json-schema": "^0.4.0",
"memfs": "^4.25.1",
"memfs": "^4.47.0",
"standard-version": "^9.5.0",
"typescript": "^5.8.3",
"vitest": "^3.2.4"
},
"dependencies": {
"@actions/core": "^1.11.1",
"@aws-sdk/client-sts": "^3.858.0",
"@smithy/node-http-handler": "^4.1.0",
"https-proxy-agent": "^7.0.6"
"@aws-sdk/client-sts": "^3.899.0",
"@smithy/node-http-handler": "^4.2.0",
"proxy-agent": "^6.5.0"
},
"keywords": [
"aws",
+2 -1
View File
@@ -6,7 +6,8 @@
"bump-minor-pre-major": false,
"bump-patch-for-minor-pre-major": false,
"draft": false,
"prerelease": false
"prerelease": false,
"exclude-paths": [".github", "dist"]
}
},
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
+49 -16
View File
@@ -2,14 +2,16 @@ import { info } from '@actions/core';
import { STSClient } from '@aws-sdk/client-sts';
import type { AwsCredentialIdentity } from '@aws-sdk/types';
import { NodeHttpHandler } from '@smithy/node-http-handler';
import { HttpsProxyAgent } from 'https-proxy-agent';
import { errorMessage } from './helpers';
import { ProxyAgent } from 'proxy-agent';
import { errorMessage, getCallerIdentity } from './helpers';
import { ProxyResolver } from './ProxyResolver';
const USER_AGENT = 'configure-aws-credentials-for-github-actions';
export interface CredentialsClientProps {
region?: string;
proxyServer?: string;
noProxy?: string;
}
export class CredentialsClient {
@@ -18,29 +20,46 @@ export class CredentialsClient {
private readonly requestHandler?: NodeHttpHandler;
constructor(props: CredentialsClientProps) {
this.region = props.region;
if (props.region !== undefined) {
this.region = props.region;
}
if (props.proxyServer) {
info('Configuring proxy handler for STS client');
const handler = new HttpsProxyAgent(props.proxyServer);
const proxyOptions: { httpProxy: string; httpsProxy: string; noProxy?: string } = {
httpProxy: props.proxyServer,
httpsProxy: props.proxyServer,
};
if (props.noProxy !== undefined) {
proxyOptions.noProxy = props.noProxy;
}
const getProxyForUrl = new ProxyResolver(proxyOptions).getProxyForUrl;
const handler = new ProxyAgent({ getProxyForUrl });
this.requestHandler = new NodeHttpHandler({
httpAgent: handler,
httpsAgent: handler,
httpAgent: handler,
});
}
}
public get stsClient(): STSClient {
if (!this._stsClient) {
this._stsClient = new STSClient({
region: this.region,
customUserAgent: USER_AGENT,
requestHandler: this.requestHandler ? this.requestHandler : undefined,
});
const config = { customUserAgent: USER_AGENT } as {
customUserAgent: string;
region?: string;
requestHandler?: NodeHttpHandler;
};
if (this.region !== undefined) config.region = this.region;
if (this.requestHandler !== undefined) config.requestHandler = this.requestHandler;
this._stsClient = new STSClient(config);
}
return this._stsClient;
}
public async validateCredentials(expectedAccessKeyId?: string, roleChaining?: boolean) {
public async validateCredentials(
expectedAccessKeyId?: string,
roleChaining?: boolean,
expectedAccountIds?: string[],
) {
let credentials: AwsCredentialIdentity;
try {
credentials = await this.loadCredentials();
@@ -50,22 +69,36 @@ export class CredentialsClient {
} catch (error) {
throw new Error(`Credentials could not be loaded, please check your action inputs: ${errorMessage(error)}`);
}
if (expectedAccountIds && expectedAccountIds.length > 0 && expectedAccountIds[0] !== '') {
let callerIdentity: Awaited<ReturnType<typeof getCallerIdentity>>;
try {
callerIdentity = await getCallerIdentity(this.stsClient);
} catch (error) {
throw new Error(`Could not validate account ID of credentials: ${errorMessage(error)}`);
}
if (!callerIdentity.Account || !expectedAccountIds.includes(callerIdentity.Account)) {
throw new Error(
`The account ID of the provided credentials (${
callerIdentity.Account ?? 'unknown'
}) does not match any of the expected account IDs: ${expectedAccountIds.join(', ')}`,
);
}
}
if (!roleChaining) {
const actualAccessKeyId = credentials.accessKeyId;
if (expectedAccessKeyId && expectedAccessKeyId !== actualAccessKeyId) {
throw new Error(
'Unexpected failure: Credentials loaded by the SDK do not match the access key ID configured by the action',
'Credentials loaded by the SDK do not match the expected access key ID configured by the action',
);
}
}
}
private async loadCredentials() {
const client = new STSClient({
requestHandler: this.requestHandler ? this.requestHandler : undefined,
});
const config = {} as { requestHandler?: NodeHttpHandler };
if (this.requestHandler !== undefined) config.requestHandler = this.requestHandler;
const client = new STSClient(config);
return client.config.credentials();
}
}
+71
View File
@@ -0,0 +1,71 @@
// Based on https://github.com/Rob--W/proxy-from-env/tree/caf8c32301afdac8b5feaf346028bd8240690144
// See https://github.com/Rob--W/proxy-from-env/blob/caf8c32301afdac8b5feaf346028bd8240690144/LICENSE
import type * as http from 'node:http';
const DEFAULT_PORTS: Record<string, number> = {
http: 80,
https: 443,
};
export interface ProxyOptions {
readonly noProxy?: string;
readonly httpsProxy?: string;
readonly httpProxy?: string;
}
export class ProxyResolver {
options: ProxyOptions;
constructor(options: ProxyOptions) {
this.options = options;
}
// This method matches the interface expected by 'proxy-agent'. It is an arrow function to bind 'this'.
public readonly getProxyForUrl = (url: string, _req: http.ClientRequest): string => {
return this.getProxyForUrlOptions(url, this.options);
};
private getProxyForUrlOptions(url: string | URL, options?: ProxyOptions): string {
let parsedUrl: URL;
try {
parsedUrl = typeof url === 'string' ? new URL(url) : url;
} catch (_) {
return ''; // Don't proxy invalid URLs.
}
const proto = parsedUrl.protocol.split(':', 1)[0];
if (!proto) return ''; // Don't proxy URLs without a protocol.
const hostname = parsedUrl.host;
const port = parseInt(parsedUrl.port || '') || DEFAULT_PORTS[proto] || 0;
if (options?.noProxy && !this.shouldProxy(hostname, port, options.noProxy)) return '';
if (proto === 'http' && options?.httpProxy) return options.httpProxy;
if (proto === 'https' && options?.httpsProxy) return options.httpsProxy;
return ''; // No proxy configured for this protocol or unknown protocol
}
private shouldProxy(hostname: string, port: number, noProxy: string): boolean {
if (!noProxy) return true;
if (noProxy === '*') return false; // Never proxy if wildcard is set.
return noProxy.split(/[,\s]/).every((proxy) => {
if (!proxy) return true; // Skip zero-length hosts.
const parsedProxy = proxy.match(/^(.+):(\d+)$/);
const parsedProxyHostname = parsedProxy ? parsedProxy[1] : proxy;
const parsedProxyPort = parsedProxy?.[2] ? parseInt(parsedProxy[2]) : 0;
if (parsedProxyPort && parsedProxyPort !== port) return true; // Skip if ports don't match.
if (parsedProxyHostname && !/^[.*]/.test(parsedProxyHostname)) {
// No wildcards, so stop proxying if there is an exact match.
return hostname !== parsedProxyHostname;
}
let cleanProxyHostname = parsedProxyHostname;
if (parsedProxyHostname && parsedProxyHostname.charAt(0) === '*') {
// Remove leading wildcard.
cleanProxyHostname = parsedProxyHostname.slice(1);
}
// Stop proxying if the hostname ends with the no_proxy host.
return !cleanProxyHostname || !hostname.endsWith(cleanProxyHostname);
});
}
}
+5 -1
View File
@@ -142,7 +142,11 @@ export async function assumeRole(params: assumeRoleParams) {
PolicyArns: managedSessionPolicies?.length ? managedSessionPolicies : undefined,
};
const keys = Object.keys(commonAssumeRoleParams) as Array<keyof typeof commonAssumeRoleParams>;
keys.forEach((k) => commonAssumeRoleParams[k] === undefined && delete commonAssumeRoleParams[k]);
keys.forEach((k) => {
if (commonAssumeRoleParams[k] === undefined) {
delete commonAssumeRoleParams[k];
}
});
// Instantiate STS client
const stsClient = credentialsClient.stsClient;
+4 -3
View File
@@ -1,5 +1,5 @@
import * as core from '@actions/core';
import { errorMessage } from '../helpers';
import { errorMessage, getBooleanInput } from '../helpers';
/**
* When the GitHub Actions job is done, clean up any environment variables that
@@ -13,8 +13,8 @@ import { errorMessage } from '../helpers';
*/
export function cleanup() {
const outputEnvCredentialsInput = core.getInput('output-env-credentials', { required: false }) || 'true';
if (outputEnvCredentialsInput === 'true') {
// Only attempt to change environment variables if we changed them in the first place
if (getBooleanInput('output-env-credentials', { required: false, default: true })) {
try {
// The GitHub Actions toolkit does not have an option to completely unset
// environment variables, so we overwrite the current value with an empty
@@ -30,6 +30,7 @@ export function cleanup() {
}
}
}
/* c8 ignore start */
if (require.main === module) {
try {
+63 -11
View File
@@ -1,5 +1,5 @@
import * as core from '@actions/core';
import type { Credentials } from '@aws-sdk/client-sts';
import type { Credentials, STSClient } from '@aws-sdk/client-sts';
import { GetCallerIdentityCommand } from '@aws-sdk/client-sts';
import type { CredentialsClient } from './CredentialsClient';
@@ -28,6 +28,7 @@ export function translateEnvVariables() {
'RETRY_MAX_ATTEMPTS',
'SPECIAL_CHARACTERS_WORKAROUND',
'USE_EXISTING_CREDENTIALS',
'NO_PROXY',
];
// Treat HTTPS_PROXY as HTTP_PROXY. Precedence is HTTPS_PROXY > HTTP_PROXY
if (process.env.HTTPS_PROXY) process.env.HTTP_PROXY = process.env.HTTPS_PROXY;
@@ -109,15 +110,26 @@ export function exportRegion(region: string, outputEnvCredentials?: boolean) {
}
}
// Obtains account ID from STS Client and sets it as output
export async function exportAccountId(credentialsClient: CredentialsClient, maskAccountId?: boolean) {
const client = credentialsClient.stsClient;
export async function getCallerIdentity(client: STSClient): Promise<{ Account: string; Arn: string; UserId?: string }> {
const identity = await client.send(new GetCallerIdentityCommand({}));
const accountId = identity.Account;
const arn = identity.Arn;
if (!accountId || !arn) {
if (!identity.Account || !identity.Arn) {
throw new Error('Could not get Account ID or ARN from STS. Did you set credentials?');
}
const result: { Account: string; Arn: string; UserId?: string } = {
Account: identity.Account,
Arn: identity.Arn,
};
if (identity.UserId !== undefined) {
result.UserId = identity.UserId;
}
return result;
}
// Obtains account ID from STS Client and sets it as output
export async function exportAccountId(credentialsClient: CredentialsClient, maskAccountId?: boolean) {
const identity = await getCallerIdentity(credentialsClient.stsClient);
const accountId = identity.Account;
const arn = identity.Arn;
if (maskAccountId) {
core.setSecret(accountId);
core.setSecret(arn);
@@ -180,15 +192,26 @@ export async function retryAndBackoff<T>(
return await fn();
} catch (err) {
if (!isRetryable) {
core.debug(`retryAndBackoff: error is not retryable: ${errorMessage(err)}`);
throw err;
}
// It's retryable, so sleep and retry.
await sleep(Math.random() * (2 ** retries * base));
retries += 1;
if (retries >= maxRetries) {
const delay = Math.random() * (2 ** retries * base);
const nextRetry = retries + 1;
core.debug(
`retryAndBackoff: attempt ${nextRetry} of ${maxRetries} failed: ${errorMessage(err)}. ` +
`Retrying after ${Math.floor(delay)}ms.`,
);
await sleep(delay);
if (nextRetry >= maxRetries) {
core.debug('retryAndBackoff: reached max retries; giving up.');
throw err;
}
return await retryAndBackoff(fn, isRetryable, maxRetries, retries, base);
return await retryAndBackoff(fn, isRetryable, maxRetries, nextRetry, base);
}
}
@@ -214,3 +237,32 @@ export async function areCredentialsValid(credentialsClient: CredentialsClient)
return false;
}
}
/**
* Like core.getBooleanInput, but respects the required option.
*
* From https://github.com/actions/toolkit/blob/6876e2a664ec02908178087905b9155e9892a437/packages/core/src/core.ts
*
* Gets the input value of the boolean type in the YAML 1.2 "core schema" specification.
* Support boolean input list: `true | True | TRUE | false | False | FALSE` .
* The return value is also in boolean type.
* ref: https://yaml.org/spec/1.2/spec.html#id2804923
*
* @param name name of the input to get
* @param options optional. See core.InputOptions. Also supports optional 'default' if the input is not set
* @returns boolean
*/
export function getBooleanInput(name: string, options?: core.InputOptions & { default?: boolean }): boolean {
const trueValue = ['true', 'True', 'TRUE'];
const falseValue = ['false', 'False', 'FALSE'];
const optionsWithoutDefault = { ...options };
delete optionsWithoutDefault.default;
const val = core.getInput(name, optionsWithoutDefault);
if (trueValue.includes(val)) return true;
if (falseValue.includes(val)) return false;
if (val === '') return options?.default ?? false;
throw new TypeError(
`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` +
`Support boolean input list: \`true | True | TRUE | false | False | FALSE\``,
);
}
+62 -51
View File
@@ -8,6 +8,7 @@ import {
exportAccountId,
exportCredentials,
exportRegion,
getBooleanInput,
retryAndBackoff,
translateEnvVariables,
unsetCredentials,
@@ -22,68 +23,68 @@ export async function run() {
try {
translateEnvVariables();
// Get inputs
// Undefined inputs are empty strings ( or empty arrays)
const AccessKeyId = core.getInput('aws-access-key-id', { required: false });
const SecretAccessKey = core.getInput('aws-secret-access-key', {
required: false,
});
const sessionTokenInput = core.getInput('aws-session-token', {
required: false,
});
const SecretAccessKey = core.getInput('aws-secret-access-key', { required: false });
const sessionTokenInput = core.getInput('aws-session-token', { required: false });
const SessionToken = sessionTokenInput === '' ? undefined : sessionTokenInput;
const region = core.getInput('aws-region', { required: true });
const roleToAssume = core.getInput('role-to-assume', { required: false });
const audience = core.getInput('audience', { required: false });
const maskAccountIdInput = core.getInput('mask-aws-account-id', { required: false }) || 'false';
const maskAccountId = maskAccountIdInput.toLowerCase() === 'true';
const roleExternalId = core.getInput('role-external-id', {
required: false,
});
const webIdentityTokenFile = core.getInput('web-identity-token-file', {
required: false,
});
const maskAccountId = getBooleanInput('mask-aws-account-id', { required: false });
const roleExternalId = core.getInput('role-external-id', { required: false });
const webIdentityTokenFile = core.getInput('web-identity-token-file', { required: false });
const roleDuration =
Number.parseInt(core.getInput('role-duration-seconds', { required: false })) || DEFAULT_ROLE_DURATION;
const roleSessionName = core.getInput('role-session-name', { required: false }) || ROLE_SESSION_NAME;
const roleSkipSessionTaggingInput = core.getInput('role-skip-session-tagging', { required: false }) || 'false';
const roleSkipSessionTagging = roleSkipSessionTaggingInput.toLowerCase() === 'true';
const roleSkipSessionTagging = getBooleanInput('role-skip-session-tagging', { required: false });
const proxyServer = core.getInput('http-proxy', { required: false }) || process.env.HTTP_PROXY;
const inlineSessionPolicy = core.getInput('inline-session-policy', {
required: false,
const inlineSessionPolicy = core.getInput('inline-session-policy', { required: false });
const managedSessionPolicies = core.getMultilineInput('managed-session-policies', { required: false }).map((p) => {
return { arn: p };
});
const managedSessionPoliciesInput = core.getMultilineInput('managed-session-policies', { required: false });
const managedSessionPolicies: { arn: string }[] = [];
const roleChainingInput = core.getInput('role-chaining', { required: false }) || 'false';
const roleChaining = roleChainingInput.toLowerCase() === 'true';
const outputCredentialsInput = core.getInput('output-credentials', { required: false }) || 'false';
const outputCredentials = outputCredentialsInput.toLowerCase() === 'true';
const outputEnvCredentialsInput = core.getInput('output-env-credentials', { required: false }) || 'true';
const outputEnvCredentials = outputEnvCredentialsInput.toLowerCase() === 'true';
const unsetCurrentCredentialsInput = core.getInput('unset-current-credentials', { required: false }) || 'false';
const unsetCurrentCredentials = unsetCurrentCredentialsInput.toLowerCase() === 'true';
const disableRetryInput = core.getInput('disable-retry', { required: false }) || 'false';
let disableRetry = disableRetryInput.toLowerCase() === 'true';
const specialCharacterWorkaroundInput =
core.getInput('special-characters-workaround', { required: false }) || 'false';
const specialCharacterWorkaround = specialCharacterWorkaroundInput.toLowerCase() === 'true';
const useExistingCredentialsInput = core.getInput('use-existing-credentials', { required: false }) || 'false';
const useExistingCredentials = useExistingCredentialsInput.toLowerCase() === 'true';
const roleChaining = getBooleanInput('role-chaining', { required: false });
const outputCredentials = getBooleanInput('output-credentials', { required: false });
const outputEnvCredentials = getBooleanInput('output-env-credentials', { required: false, default: true });
const unsetCurrentCredentials = getBooleanInput('unset-current-credentials', { required: false });
let disableRetry = getBooleanInput('disable-retry', { required: false });
const specialCharacterWorkaround = getBooleanInput('special-characters-workaround', { required: false });
const useExistingCredentials = core.getInput('use-existing-credentials', { required: false });
let maxRetries = Number.parseInt(core.getInput('retry-max-attempts', { required: false })) || 12;
switch (true) {
case specialCharacterWorkaround:
// 😳
disableRetry = false;
maxRetries = 12;
break;
case maxRetries < 1:
maxRetries = 1;
break;
const expectedAccountIds = core
.getInput('allowed-account-ids', { required: false })
.split(',')
.map((s) => s.trim());
const forceSkipOidc = getBooleanInput('force-skip-oidc', { required: false });
const noProxy = core.getInput('no-proxy', { required: false });
const globalTimeout = Number.parseInt(core.getInput('action-timeout-s', { required: false })) || 0;
let timeoutId: NodeJS.Timeout | undefined;
if (globalTimeout > 0) {
core.info(`Setting a global timeout of ${globalTimeout} seconds for the action`);
timeoutId = setTimeout(() => {
core.setFailed(`Action timed out after ${globalTimeout} seconds`);
process.exit(1);
}, globalTimeout * 1000);
}
for (const managedSessionPolicy of managedSessionPoliciesInput) {
managedSessionPolicies.push({ arn: managedSessionPolicy });
if (forceSkipOidc && roleToAssume && !AccessKeyId && !webIdentityTokenFile) {
throw new Error(
"If 'force-skip-oidc' is true and 'role-to-assume' is set, 'aws-access-key-id' or 'web-identity-token-file' must be set",
);
}
if (specialCharacterWorkaround) {
// 😳
disableRetry = false;
maxRetries = 12;
} else if (maxRetries < 1) {
maxRetries = 1;
}
// Logic to decide whether to attempt to use OIDC or not
const useGitHubOIDCProvider = () => {
if (forceSkipOidc) return false;
// The `ACTIONS_ID_TOKEN_REQUEST_TOKEN` environment variable is set when the `id-token` permission is granted.
// This is necessary to authenticate with OIDC, but not strictly set just for OIDC. If it is not set and all other
// checks pass, it is likely but not guaranteed that the user needs but lacks this permission in their workflow.
@@ -119,7 +120,10 @@ export async function run() {
exportRegion(region, outputEnvCredentials);
// Instantiate credentials client
const credentialsClient = new CredentialsClient({ region, proxyServer });
const clientProps: { region: string; proxyServer?: string; noProxy?: string } = { region };
if (proxyServer) clientProps.proxyServer = proxyServer;
if (noProxy) clientProps.noProxy = noProxy;
const credentialsClient = new CredentialsClient(clientProps);
let sourceAccountId: string;
let webIdentityToken: string;
@@ -128,6 +132,7 @@ export async function run() {
const validCredentials = await areCredentialsValid(credentialsClient);
if (validCredentials) {
core.notice('Pre-existing credentials are valid. No need to generate new ones.');
if (timeoutId) clearTimeout(timeoutId);
return;
}
core.notice('No valid credentials exist. Running as normal.');
@@ -158,7 +163,7 @@ export async function run() {
exportCredentials({ AccessKeyId, SecretAccessKey, SessionToken }, outputCredentials, outputEnvCredentials);
} else if (!webIdentityTokenFile && !roleChaining) {
// Proceed only if credentials can be picked up
await credentialsClient.validateCredentials();
await credentialsClient.validateCredentials(undefined, roleChaining, expectedAccountIds);
sourceAccountId = await exportAccountId(credentialsClient, maskAccountId);
}
@@ -166,7 +171,7 @@ export async function run() {
// Validate that the SDK can actually pick up credentials.
// This validates cases where this action is using existing environment credentials,
// and cases where the user intended to provide input credentials but the secrets inputs resolved to empty strings.
await credentialsClient.validateCredentials(AccessKeyId, roleChaining);
await credentialsClient.validateCredentials(AccessKeyId, roleChaining, expectedAccountIds);
sourceAccountId = await exportAccountId(credentialsClient, maskAccountId);
}
@@ -201,7 +206,11 @@ export async function run() {
// is set to `true` then we are NOT in a self-hosted runner.
// Second: Customer provided credentials manually (IAM User keys stored in GH Secrets)
if (!process.env.GITHUB_ACTIONS || AccessKeyId) {
await credentialsClient.validateCredentials(roleCredentials.Credentials?.AccessKeyId);
await credentialsClient.validateCredentials(
roleCredentials.Credentials?.AccessKeyId,
roleChaining,
expectedAccountIds,
);
}
if (outputEnvCredentials) {
await exportAccountId(credentialsClient, maskAccountId);
@@ -209,11 +218,13 @@ export async function run() {
} else {
core.info('Proceeding with IAM user credentials');
}
// Clear timeout on successful completion
if (timeoutId) clearTimeout(timeoutId);
} catch (error) {
core.setFailed(errorMessage(error));
const showStackTrace = process.env.SHOW_STACK_TRACE;
if (showStackTrace === 'true') {
throw error;
}
+100
View File
@@ -0,0 +1,100 @@
import type * as http from 'node:http';
import { describe, expect, test } from 'vitest';
import { type ProxyOptions, ProxyResolver } from '../src/ProxyResolver';
describe('ProxyResolver', () => {
const mockReq = {} as http.ClientRequest;
test('returns http proxy for http URLs', () => {
const options: ProxyOptions = { httpProxy: 'http://proxy:8080' };
const resolver = new ProxyResolver(options);
expect(resolver.getProxyForUrl('http://example.com', mockReq)).toBe('http://proxy:8080');
});
test('returns https proxy for https URLs', () => {
const options: ProxyOptions = { httpsProxy: 'https://proxy:8080' };
const resolver = new ProxyResolver(options);
expect(resolver.getProxyForUrl('https://example.com', mockReq)).toBe('https://proxy:8080');
});
test('returns empty string when no proxy configured', () => {
const resolver = new ProxyResolver({});
expect(resolver.getProxyForUrl('http://example.com', mockReq)).toBe('');
});
test('respects noProxy setting', () => {
const options: ProxyOptions = {
httpProxy: 'http://proxy:8080',
noProxy: 'example.com',
};
const resolver = new ProxyResolver(options);
expect(resolver.getProxyForUrl('http://example.com', mockReq)).toBe('');
expect(resolver.getProxyForUrl('http://other.com', mockReq)).toBe('http://proxy:8080');
});
test('handles invalid URLs', () => {
const resolver = new ProxyResolver({ httpProxy: 'http://proxy:8080' });
expect(resolver.getProxyForUrl('invalid-url', mockReq)).toBe('');
});
test('handles wildcard noProxy', () => {
const options: ProxyOptions = {
httpProxy: 'http://proxy:8080',
noProxy: '*',
};
const resolver = new ProxyResolver(options);
expect(resolver.getProxyForUrl('http://example.com', mockReq)).toBe('');
});
test('handles comma-separated noProxy list', () => {
const options: ProxyOptions = {
httpProxy: 'http://proxy:8080',
noProxy: 'example.com,test.com',
};
const resolver = new ProxyResolver(options);
expect(resolver.getProxyForUrl('http://example.com', mockReq)).toBe('');
expect(resolver.getProxyForUrl('http://test.com', mockReq)).toBe('');
expect(resolver.getProxyForUrl('http://other.com', mockReq)).toBe('http://proxy:8080');
});
test('handles port-specific noProxy', () => {
const options: ProxyOptions = {
httpProxy: 'http://proxy:8080',
noProxy: 'example.com:80',
};
const resolver = new ProxyResolver(options);
expect(resolver.getProxyForUrl('http://example.com', mockReq)).toBe('');
expect(resolver.getProxyForUrl('http://example.com:8080', mockReq)).toBe('http://proxy:8080');
});
test('handles wildcard domain noProxy', () => {
const options: ProxyOptions = {
httpProxy: 'http://proxy:8080',
noProxy: '*.example.com',
};
const resolver = new ProxyResolver(options);
expect(resolver.getProxyForUrl('http://sub.example.com', mockReq)).toBe('');
expect(resolver.getProxyForUrl('http://example.com', mockReq)).toBe('http://proxy:8080');
expect(resolver.getProxyForUrl('http://other.com', mockReq)).toBe('http://proxy:8080');
});
test('handles empty noProxy entries', () => {
const options: ProxyOptions = {
httpProxy: 'http://proxy:8080',
noProxy: 'example.com, ,test.com',
};
const resolver = new ProxyResolver(options);
expect(resolver.getProxyForUrl('http://example.com', mockReq)).toBe('');
expect(resolver.getProxyForUrl('http://test.com', mockReq)).toBe('');
});
});
+35
View File
@@ -61,4 +61,39 @@ describe('Configure AWS Credentials helpers', {}, () => {
expect(core.setSecret).toHaveBeenCalledTimes(3);
expect(core.exportVariable).toHaveBeenCalledTimes(0);
});
it('verifies credentials without special characters', {}, () => {
expect(helpers.verifyKeys({ AccessKeyId: 'AKIATEST', SecretAccessKey: 'secretkey' })).toBe(true);
expect(helpers.verifyKeys({ AccessKeyId: 'AKIA!@#$', SecretAccessKey: 'secret' })).toBe(false);
expect(helpers.verifyKeys(undefined)).toBe(false);
});
it('translates environment variables', {}, () => {
process.env.AWS_REGION = 'us-east-1';
process.env.HTTPS_PROXY = 'https://proxy:8080';
helpers.translateEnvVariables();
expect(process.env['INPUT_AWS-REGION']).toBe('us-east-1');
expect(process.env.HTTP_PROXY).toBe('https://proxy:8080');
});
it('handles getBooleanInput correctly', {}, () => {
vi.spyOn(core, 'getInput').mockReturnValue('true');
expect(helpers.getBooleanInput('test')).toBe(true);
vi.spyOn(core, 'getInput').mockReturnValue('false');
expect(helpers.getBooleanInput('test')).toBe(false);
vi.spyOn(core, 'getInput').mockReturnValue('');
expect(helpers.getBooleanInput('test', { default: true })).toBe(true);
vi.spyOn(core, 'getInput').mockReturnValue('invalid');
expect(() => helpers.getBooleanInput('test')).toThrow();
});
it('clears session token when not provided', {}, () => {
vi.spyOn(core, 'exportVariable').mockImplementation(() => {});
process.env.AWS_SESSION_TOKEN = 'old-token';
helpers.exportCredentials({ AccessKeyId: 'test', SecretAccessKey: 'test' }, false, true);
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', '');
});
});
+429 -17
View File
@@ -334,6 +334,398 @@ describe('Configure AWS Credentials', {}, () => {
});
});
describe('Force Skip OIDC', {}, () => {
beforeEach(() => {
vi.clearAllMocks();
mockedSTSClient.reset();
});
it('skips OIDC when force-skip-oidc is true with IAM credentials', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.IAM_ASSUMEROLE_INPUTS,
'force-skip-oidc': 'true',
}),
);
vi.spyOn(core, 'getIDToken').mockResolvedValue('testoidctoken');
mockedSTSClient.on(AssumeRoleCommand).resolves(mocks.outputs.STS_CREDENTIALS);
mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY });
// biome-ignore lint/suspicious/noExplicitAny: any required to mock private method
vi.spyOn(CredentialsClient.prototype as any, 'loadCredentials')
.mockResolvedValueOnce({ accessKeyId: 'MYAWSACCESSKEYID' })
.mockResolvedValueOnce({ accessKeyId: 'STSAWSACCESSKEYID' });
process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'fake-token';
await run();
expect(core.getIDToken).not.toHaveBeenCalled();
expect(core.setFailed).not.toHaveBeenCalled();
});
it('skips OIDC when force-skip-oidc is true with web identity token file', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.WEBIDENTITY_TOKEN_FILE_INPUTS,
'force-skip-oidc': 'true',
}),
);
vi.spyOn(core, 'getIDToken').mockResolvedValue('testoidctoken');
mockedSTSClient.on(AssumeRoleWithWebIdentityCommand).resolves(mocks.outputs.STS_CREDENTIALS);
mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY });
process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'fake-token';
vi.mock('node:fs');
vol.reset();
fs.mkdirSync('/home/github', { recursive: true });
fs.writeFileSync('/home/github/file.txt', 'test-token');
await run();
expect(core.getIDToken).not.toHaveBeenCalled();
expect(core.info).toHaveBeenCalledWith('Assuming role with web identity token file');
expect(core.setFailed).not.toHaveBeenCalled();
});
it('fails when force-skip-oidc is true but no alternative credentials provided', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'aws-region': 'fake-region-1',
'force-skip-oidc': 'true',
}),
);
process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'fake-token';
await run();
expect(core.setFailed).toHaveBeenCalledWith(
"If 'force-skip-oidc' is true and 'role-to-assume' is set, 'aws-access-key-id' or 'web-identity-token-file' must be set",
);
});
it('allows force-skip-oidc without role-to-assume', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.IAM_USER_INPUTS,
'force-skip-oidc': 'true',
}),
);
vi.spyOn(core, 'getIDToken').mockResolvedValue('testoidctoken');
mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY });
// biome-ignore lint/suspicious/noExplicitAny: any required to mock private method
vi.spyOn(CredentialsClient.prototype as any, 'loadCredentials').mockResolvedValue({
accessKeyId: 'MYAWSACCESSKEYID',
});
process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'fake-token';
await run();
expect(core.getIDToken).not.toHaveBeenCalled();
expect(core.info).toHaveBeenCalledWith('Proceeding with IAM user credentials');
expect(core.setFailed).not.toHaveBeenCalled();
});
it('uses OIDC when force-skip-oidc is false (default behavior)', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.GH_OIDC_INPUTS,
'force-skip-oidc': 'false',
}),
);
vi.spyOn(core, 'getIDToken').mockResolvedValue('testoidctoken');
mockedSTSClient.on(AssumeRoleWithWebIdentityCommand).resolves(mocks.outputs.STS_CREDENTIALS);
mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY });
process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'fake-token';
await run();
expect(core.getIDToken).toHaveBeenCalledWith('');
expect(core.info).toHaveBeenCalledWith('Assuming role with OIDC');
expect(core.setFailed).not.toHaveBeenCalled();
});
it('uses OIDC when force-skip-oidc is not set (default behavior)', async () => {
vi.spyOn(core, 'getInput').mockImplementation(mocks.getInput(mocks.GH_OIDC_INPUTS));
vi.spyOn(core, 'getIDToken').mockResolvedValue('testoidctoken');
mockedSTSClient.on(AssumeRoleWithWebIdentityCommand).resolves(mocks.outputs.STS_CREDENTIALS);
mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY });
process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'fake-token';
await run();
expect(core.getIDToken).toHaveBeenCalledWith('');
expect(core.info).toHaveBeenCalledWith('Assuming role with OIDC');
expect(core.setFailed).not.toHaveBeenCalled();
});
it('works with role chaining when force-skip-oidc is true', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.EXISTING_ROLE_INPUTS,
'force-skip-oidc': 'true',
'aws-access-key-id': 'MYAWSACCESSKEYID',
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
}),
);
vi.spyOn(core, 'getIDToken').mockResolvedValue('testoidctoken');
mockedSTSClient.on(AssumeRoleCommand).resolves(mocks.outputs.STS_CREDENTIALS);
mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY });
// biome-ignore lint/suspicious/noExplicitAny: any required to mock private method
vi.spyOn(CredentialsClient.prototype as any, 'loadCredentials')
.mockResolvedValueOnce({ accessKeyId: 'MYAWSACCESSKEYID' })
.mockResolvedValueOnce({ accessKeyId: 'STSAWSACCESSKEYID' });
process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'fake-token';
await run();
expect(core.getIDToken).not.toHaveBeenCalled();
expect(core.setFailed).not.toHaveBeenCalled();
});
});
describe('Account ID Validation', {}, () => {
beforeEach(() => {
vi.clearAllMocks();
mockedSTSClient.reset();
});
it('succeeds when account ID matches allowed list', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.IAM_USER_INPUTS,
'allowed-account-ids': '111111111111',
}),
);
mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY });
// biome-ignore lint/suspicious/noExplicitAny: any required to mock private method
vi.spyOn(CredentialsClient.prototype as any, 'loadCredentials').mockResolvedValue({
accessKeyId: 'MYAWSACCESSKEYID',
});
await run();
expect(core.setFailed).not.toHaveBeenCalled();
expect(core.info).toHaveBeenCalledWith('Proceeding with IAM user credentials');
});
it('succeeds with multiple allowed account IDs when account matches', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.IAM_USER_INPUTS,
'allowed-account-ids': '999999999999,111111111111,222222222222',
}),
);
mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY });
// biome-ignore lint/suspicious/noExplicitAny: any required to mock private method
vi.spyOn(CredentialsClient.prototype as any, 'loadCredentials').mockResolvedValue({
accessKeyId: 'MYAWSACCESSKEYID',
});
await run();
expect(core.setFailed).not.toHaveBeenCalled();
});
it('fails when account ID does not match allowed list', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.IAM_USER_INPUTS,
'allowed-account-ids': '999999999999',
}),
);
mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY });
// biome-ignore lint/suspicious/noExplicitAny: any required to mock private method
vi.spyOn(CredentialsClient.prototype as any, 'loadCredentials').mockResolvedValue({
accessKeyId: 'MYAWSACCESSKEYID',
});
await run();
expect(core.setFailed).toHaveBeenCalledWith(
'The account ID of the provided credentials (111111111111) does not match any of the expected account IDs: 999999999999',
);
});
it('fails when account ID does not match any in multiple allowed accounts', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.IAM_USER_INPUTS,
'allowed-account-ids': '999999999999,888888888888',
}),
);
mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY });
// biome-ignore lint/suspicious/noExplicitAny: any required to mock private method
vi.spyOn(CredentialsClient.prototype as any, 'loadCredentials').mockResolvedValue({
accessKeyId: 'MYAWSACCESSKEYID',
});
await run();
expect(core.setFailed).toHaveBeenCalledWith(
'The account ID of the provided credentials (111111111111) does not match any of the expected account IDs: 999999999999, 888888888888',
);
});
it('works with assume role when account ID matches', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.IAM_ASSUMEROLE_INPUTS,
'allowed-account-ids': '111111111111',
}),
);
mockedSTSClient.on(AssumeRoleCommand).resolves(mocks.outputs.STS_CREDENTIALS);
mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY });
// biome-ignore lint/suspicious/noExplicitAny: any required to mock private method
vi.spyOn(CredentialsClient.prototype as any, 'loadCredentials')
.mockResolvedValueOnce({ accessKeyId: 'MYAWSACCESSKEYID' })
.mockResolvedValueOnce({ accessKeyId: 'STSAWSACCESSKEYID' });
await run();
expect(core.setFailed).not.toHaveBeenCalled();
expect(core.info).toHaveBeenCalledWith('Authenticated as assumedRoleId AROAFAKEASSUMEDROLEID');
});
it('works with OIDC when account ID matches', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.GH_OIDC_INPUTS,
'allowed-account-ids': '111111111111',
}),
);
vi.spyOn(core, 'getIDToken').mockResolvedValue('testoidctoken');
mockedSTSClient.on(AssumeRoleWithWebIdentityCommand).resolves(mocks.outputs.STS_CREDENTIALS);
mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY });
process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'fake-token';
await run();
expect(core.setFailed).not.toHaveBeenCalled();
expect(core.info).toHaveBeenCalledWith('Authenticated as assumedRoleId AROAFAKEASSUMEDROLEID');
});
it('handles GetCallerIdentity API failure gracefully', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.IAM_USER_INPUTS,
'allowed-account-ids': '111111111111',
}),
);
mockedSTSClient.on(GetCallerIdentityCommand).rejects(new Error('API Error'));
// biome-ignore lint/suspicious/noExplicitAny: any required to mock private method
vi.spyOn(CredentialsClient.prototype as any, 'loadCredentials').mockResolvedValue({
accessKeyId: 'MYAWSACCESSKEYID',
});
await run();
expect(core.setFailed).toHaveBeenCalledWith('Could not validate account ID of credentials: API Error');
});
it('ignores validation when allowed-account-ids is empty', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.IAM_USER_INPUTS,
'allowed-account-ids': '',
}),
);
mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY });
// biome-ignore lint/suspicious/noExplicitAny: any required to mock private method
vi.spyOn(CredentialsClient.prototype as any, 'loadCredentials').mockResolvedValue({
accessKeyId: 'MYAWSACCESSKEYID',
});
await run();
expect(core.setFailed).not.toHaveBeenCalled();
expect(core.info).toHaveBeenCalledWith('Proceeding with IAM user credentials');
});
it('handles whitespace in allowed-account-ids input', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.IAM_USER_INPUTS,
'allowed-account-ids': ' 111111111111 , 222222222222 ',
}),
);
mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY });
// biome-ignore lint/suspicious/noExplicitAny: any required to mock private method
vi.spyOn(CredentialsClient.prototype as any, 'loadCredentials').mockResolvedValue({
accessKeyId: 'MYAWSACCESSKEYID',
});
await run();
expect(core.setFailed).not.toHaveBeenCalled();
});
});
describe('Global Timeout Configuration', {}, () => {
beforeEach(() => {
vi.spyOn(core, 'getInput').mockImplementation(mocks.getInput(mocks.IAM_USER_INPUTS));
mockedSTSClient.on(GetCallerIdentityCommand).resolvesOnce({ ...mocks.outputs.GET_CALLER_IDENTITY });
// biome-ignore lint/suspicious/noExplicitAny: any required to mock private method
vi.spyOn(CredentialsClient.prototype as any, 'loadCredentials').mockResolvedValueOnce({
accessKeyId: 'MYAWSACCESSKEYID',
});
});
it('sets timeout when action-timeout-s is provided', async () => {
const setTimeoutSpy = vi.spyOn(global, 'setTimeout');
const clearTimeoutSpy = vi.spyOn(global, 'clearTimeout');
const infoSpy = vi.spyOn(core, 'info');
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.IAM_USER_INPUTS,
'action-timeout-s': '30',
}),
);
await run();
expect(infoSpy).toHaveBeenCalledWith('Setting a global timeout of 30 seconds for the action');
expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), 30000);
expect(clearTimeoutSpy).toHaveBeenCalledWith(expect.any(Object));
expect(core.setFailed).not.toHaveBeenCalled();
});
it('does not set timeout when action-timeout-s is 0', async () => {
const setTimeoutSpy = vi.spyOn(global, 'setTimeout');
const infoSpy = vi.spyOn(core, 'info');
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.IAM_USER_INPUTS,
'action-timeout-s': '0',
}),
);
await run();
expect(infoSpy).not.toHaveBeenCalledWith(expect.stringContaining('Setting a global timeout'));
expect(setTimeoutSpy).not.toHaveBeenCalled();
expect(core.setFailed).not.toHaveBeenCalled();
});
it('does not set timeout when action-timeout-s is not provided', async () => {
const setTimeoutSpy = vi.spyOn(global, 'setTimeout');
const infoSpy = vi.spyOn(core, 'info');
await run();
expect(infoSpy).not.toHaveBeenCalledWith(expect.stringContaining('Setting a global timeout'));
expect(setTimeoutSpy).not.toHaveBeenCalled();
expect(core.setFailed).not.toHaveBeenCalled();
});
it('timeout callback calls setFailed and exits process', async () => {
const setTimeoutSpy = vi.spyOn(global, 'setTimeout');
const processExitSpy = vi.spyOn(process, 'exit').mockImplementation(() => undefined as never);
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.IAM_USER_INPUTS,
'action-timeout-s': '5',
}),
);
await run();
// Get the timeout callback function
const timeoutCallback = setTimeoutSpy.mock.calls[0][0] as () => void;
// Execute the timeout callback
timeoutCallback();
expect(core.setFailed).toHaveBeenCalledWith('Action timed out after 5 seconds');
expect(processExitSpy).toHaveBeenCalledWith(1);
});
});
describe('HTTP Proxy Configuration', {}, () => {
beforeEach(() => {
vi.spyOn(core, 'getInput').mockImplementation(mocks.getInput(mocks.GH_OIDC_INPUTS));
@@ -348,12 +740,12 @@ describe('Configure AWS Credentials', {}, () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.GH_OIDC_INPUTS,
'http-proxy': 'http://proxy.example.com:8080'
})
'http-proxy': 'http://proxy.example.com:8080',
}),
);
await run();
expect(infoSpy).toHaveBeenCalledWith('Configuring proxy handler for STS client');
expect(core.setFailed).not.toHaveBeenCalled();
});
@@ -361,9 +753,9 @@ describe('Configure AWS Credentials', {}, () => {
it('configures proxy from HTTP_PROXY environment variable', async () => {
const infoSpy = vi.spyOn(core, 'info');
process.env.HTTP_PROXY = 'http://proxy.example.com:8080';
await run();
expect(infoSpy).toHaveBeenCalledWith('Configuring proxy handler for STS client');
expect(core.setFailed).not.toHaveBeenCalled();
});
@@ -371,9 +763,9 @@ describe('Configure AWS Credentials', {}, () => {
it('configures proxy from HTTPS_PROXY environment variable', async () => {
const infoSpy = vi.spyOn(core, 'info');
process.env.HTTPS_PROXY = 'https://proxy.example.com:8080';
await run();
expect(infoSpy).toHaveBeenCalledWith('Configuring proxy handler for STS client');
expect(core.setFailed).not.toHaveBeenCalled();
});
@@ -384,30 +776,50 @@ describe('Configure AWS Credentials', {}, () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.GH_OIDC_INPUTS,
'http-proxy': 'http://input-proxy.example.com:8080'
})
'http-proxy': 'http://input-proxy.example.com:8080',
}),
);
await run();
expect(infoSpy).toHaveBeenCalledWith('Configuring proxy handler for STS client');
expect(core.setFailed).not.toHaveBeenCalled();
});
it('properly configures proxy agent in STS client', async () => {
const infoSpy = vi.spyOn(core, 'info');
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.GH_OIDC_INPUTS,
'http-proxy': 'http://proxy.example.com:8080'
})
'http-proxy': 'http://proxy.example.com:8080',
}),
);
await run();
expect(infoSpy).toHaveBeenCalledWith('Configuring proxy handler for STS client');
expect(core.setFailed).not.toHaveBeenCalled();
});
it('configures no-proxy setting', async () => {
vi.spyOn(core, 'getInput').mockImplementation(
mocks.getInput({
...mocks.GH_OIDC_INPUTS,
'http-proxy': 'http://proxy.example.com:8080',
'no-proxy': 'localhost,127.0.0.1',
}),
);
await run();
expect(core.setFailed).not.toHaveBeenCalled();
});
it('works without proxy configuration', async () => {
await run();
expect(core.setFailed).not.toHaveBeenCalled();
});
});
});
+1 -1
View File
@@ -3,7 +3,7 @@
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"strict": true,
"exactOptionalPropertyTypes": false,
"exactOptionalPropertyTypes": true,
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"noImplicitReturns": true,