From ffe84397b120577b489e9b803d264d3721183f52 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Feb 2024 18:14:21 +0000 Subject: [PATCH 01/82] chore(deps): update chromaui/action digest to c906769 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/verify_storybook.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/verify_storybook.yml b/.github/workflows/verify_storybook.yml index 537499016c..70fb16ac48 100644 --- a/.github/workflows/verify_storybook.yml +++ b/.github/workflows/verify_storybook.yml @@ -51,7 +51,7 @@ jobs: - run: yarn build-storybook - - uses: chromaui/action@a7938ff070f700b48e271857366b0564d65e3e5b # v10 + - uses: chromaui/action@c9067691aca4a28d6fbb40d9eea6e144369fbcae # v10 with: token: ${{ secrets.GITHUB_TOKEN }} # projectToken intentionally shared to allow collaborators to run Chromatic on forks From b66e306c723bee29f281a6a58543043369af251a Mon Sep 17 00:00:00 2001 From: swnia <119884634+swnia@users.noreply.github.com> Date: Thu, 15 Feb 2024 09:47:27 +0100 Subject: [PATCH 02/82] Update resource type list As the kubernetes plugin searches for the type `kubernetes-cluster` and not `cluster` the documentation should provide examples that are recognised in the ecosystem. Signed-off-by: swnia <119884634+swnia@users.noreply.github.com> --- docs/features/software-catalog/descriptor-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index cc2b3d1c7b..054b727e78 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -1119,7 +1119,7 @@ Some common values for this field could be: - `database` - `s3-bucket` -- `cluster` +- `kubernetes-cluster` ### `spec.system` [optional] From e3b817f01d5ad91e068502957621ad9e39397a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 15 Feb 2024 10:08:59 +0100 Subject: [PATCH 03/82] do less renovate pinning - starting out with docker images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .github/renovate.json5 | 13 ++++++++++--- .github/workflows/ci.yml | 6 +++--- .github/workflows/deploy_packages.yml | 6 +++--- .github/workflows/verify_e2e-linux.yml | 2 +- contrib/.devcontainer/Dockerfile | 2 +- .../Rails.dockerfile | 2 +- .../scripts/Cookiecutter.dockerfile | 4 ++-- 7 files changed, 21 insertions(+), 14 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 828e5f5481..139e8ce8a2 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -3,7 +3,11 @@ labels: ['dependencies'], - extends: ['config:best-practices', ':gitSignOff'], + extends: [ + 'config:best-practices', + ':gitSignOff', + 'default:pinDigestsDisabled', + ], // do not pin dev dependencies, which are part of the best-practices preset ignorePresets: [':pinDevDependencies'], @@ -12,8 +16,11 @@ postUpdateOptions: ['yarnDedupeHighest'], rangeStrategy: 'update-lockfile', - // @elastic/elasticsearch is ignored due to licensing issues. See #10992 - ignoreDeps: ['@elastic/elasticsearch', 'event-source-polyfill'], + ignoreDeps: [ + // ignored due to licensing issues. See #10992 + '@elastic/elasticsearch', + 'event-source-polyfill', + ], packageRules: [ { matchSourceUrlPrefixes: ['https://github.com/spotify/web-scripts'], diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c8d009f8e..5df2a2509d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -155,7 +155,7 @@ jobs: name: Test ${{ matrix.node-version }} services: postgres16: - image: postgres:16@sha256:39d764950f22cfe878661247bb15cb344169dc3d55c9d4676303a2ef8675c057 + image: postgres:16 env: POSTGRES_PASSWORD: postgres options: >- @@ -166,7 +166,7 @@ jobs: ports: - 5432/tcp postgres12: - image: postgres:12@sha256:7a4c3f690fa767db8aaa4a9da3870037535307cc7f8f1880f1d7275a1be29b4d + image: postgres:12 env: POSTGRES_PASSWORD: postgres options: >- @@ -177,7 +177,7 @@ jobs: ports: - 5432/tcp mysql8: - image: mysql:8@sha256:343b82684a6b05812c58ca20ccd3af8bcf8a5f48b1842f251c54379bfce848f9 + image: mysql:8 env: MYSQL_ROOT_PASSWORD: root options: >- diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index 707e70ed56..c91fec948e 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -23,7 +23,7 @@ jobs: services: postgres16: - image: postgres:16@sha256:39d764950f22cfe878661247bb15cb344169dc3d55c9d4676303a2ef8675c057 + image: postgres:16 env: POSTGRES_PASSWORD: postgres options: >- @@ -34,7 +34,7 @@ jobs: ports: - 5432/tcp postgres12: - image: postgres:12@sha256:7a4c3f690fa767db8aaa4a9da3870037535307cc7f8f1880f1d7275a1be29b4d + image: postgres:12 env: POSTGRES_PASSWORD: postgres options: >- @@ -45,7 +45,7 @@ jobs: ports: - 5432/tcp mysql8: - image: mysql:8@sha256:343b82684a6b05812c58ca20ccd3af8bcf8a5f48b1842f251c54379bfce848f9 + image: mysql:8 env: MYSQL_ROOT_PASSWORD: root options: >- diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index 2da0739e64..dc62ce5725 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -19,7 +19,7 @@ jobs: services: postgres: - image: postgres:12@sha256:7a4c3f690fa767db8aaa4a9da3870037535307cc7f8f1880f1d7275a1be29b4d + image: postgres:12 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres diff --git a/contrib/.devcontainer/Dockerfile b/contrib/.devcontainer/Dockerfile index 5c21c73acc..6407aa26dd 100644 --- a/contrib/.devcontainer/Dockerfile +++ b/contrib/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/devcontainers/typescript-node:20@sha256:381a1fde32704f229b439ade94816d5619f710e35698982ec35afcd9384ae6cf +FROM mcr.microsoft.com/devcontainers/typescript-node:20 RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ && apt-get -y install chromium \ diff --git a/plugins/scaffolder-backend-module-rails/Rails.dockerfile b/plugins/scaffolder-backend-module-rails/Rails.dockerfile index aa9ccf19f3..8ea3fc370a 100644 --- a/plugins/scaffolder-backend-module-rails/Rails.dockerfile +++ b/plugins/scaffolder-backend-module-rails/Rails.dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.3@sha256:24af4f0bf0af61d04a5ead4f43e7ad468a1b2ff05844d7780555a13a78615ced +FROM ruby:3.3 RUN apt-get update -qq && \ apt-get install -y nodejs postgresql-client git && \ diff --git a/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile b/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile index 33c6ad3788..6aa3c0dfa0 100644 --- a/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile +++ b/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.18@sha256:11e21d7b981a59554b3f822c49f6e9f57b6068bb74f49c4cd5cc4c663c7e5160 +FROM alpine:3.18 RUN apk add --update \ git \ @@ -8,4 +8,4 @@ RUN apk add --update \ g++ && \ pip install cookiecutter && \ apk del g++ py-pip python-dev && \ - rm -rf /var/cache/apk/* + rm -rf /var/cache/apk/* From 79f237398aac7624bc7248c8725e123bf8e4e742 Mon Sep 17 00:00:00 2001 From: blam Date: Thu, 15 Feb 2024 10:54:38 +0100 Subject: [PATCH 04/82] chore: remove immer dependency Signed-off-by: blam --- plugins/scaffolder-react/package.json | 1 - plugins/scaffolder/package.json | 1 - yarn.lock | 4 +--- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index 0263efd4f4..94b6b044dc 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -68,7 +68,6 @@ "classnames": "^2.2.6", "flatted": "3.2.9", "humanize-duration": "^3.25.1", - "immer": "^9.0.1", "json-schema": "^0.4.0", "json-schema-library": "^7.3.9", "lodash": "^4.17.21", diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index c93de86cc9..3acc3270aa 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -78,7 +78,6 @@ "event-source-polyfill": "^1.0.31", "git-url-parse": "^14.0.0", "humanize-duration": "^3.25.1", - "immer": "^9.0.1", "json-schema": "^0.4.0", "json-schema-library": "^7.3.9", "jszip": "^3.10.1", diff --git a/yarn.lock b/yarn.lock index 6280775f8b..154afc7c66 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8725,7 +8725,6 @@ __metadata: classnames: ^2.2.6 flatted: 3.2.9 humanize-duration: ^3.25.1 - immer: ^9.0.1 json-schema: ^0.4.0 json-schema-library: ^7.3.9 lodash: ^4.17.21 @@ -8790,7 +8789,6 @@ __metadata: event-source-polyfill: ^1.0.31 git-url-parse: ^14.0.0 humanize-duration: ^3.25.1 - immer: ^9.0.1 json-schema: ^0.4.0 json-schema-library: ^7.3.9 jszip: ^3.10.1 @@ -30474,7 +30472,7 @@ __metadata: languageName: node linkType: hard -"immer@npm:^9.0.1, immer@npm:^9.0.6, immer@npm:^9.0.7": +"immer@npm:^9.0.6, immer@npm:^9.0.7": version: 9.0.21 resolution: "immer@npm:9.0.21" checksum: 70e3c274165995352f6936695f0ef4723c52c92c92dd0e9afdfe008175af39fa28e76aafb3a2ca9d57d1fb8f796efc4dd1e1cc36f18d33fa5b74f3dfb0375432 From 3dff4b0b80c98a59b973d2928ab16776cb328218 Mon Sep 17 00:00:00 2001 From: blam Date: Thu, 15 Feb 2024 10:56:13 +0100 Subject: [PATCH 05/82] chore: deps Signed-off-by: blam --- .changeset/tidy-cycles-obey.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/tidy-cycles-obey.md diff --git a/.changeset/tidy-cycles-obey.md b/.changeset/tidy-cycles-obey.md new file mode 100644 index 0000000000..4a002269e1 --- /dev/null +++ b/.changeset/tidy-cycles-obey.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-react': patch +'@backstage/plugin-scaffolder': patch +--- + +Remove unused deps From 5c5154a8f85dc3016890ac1c61da3870e27c6da0 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 12:42:50 +0100 Subject: [PATCH 06/82] docs/plugins/new-backend-system: remove await Signed-off-by: Patrik Oldsberg --- docs/plugins/new-backend-system.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plugins/new-backend-system.md b/docs/plugins/new-backend-system.md index 0fc44f283f..08ed7e73c7 100644 --- a/docs/plugins/new-backend-system.md +++ b/docs/plugins/new-backend-system.md @@ -26,7 +26,7 @@ const backend = createBackend(); backend.add(import('@backstage/plugin-catalog-backend')); // Start up the backend -await backend.start(); +backend.start(); ``` One notable change that helped achieve this much slimmer backend setup is the introduction of a system for dependency injection, which is very similar to the one in the Backstage frontend. From 3d5c6680f6b83fa8c9bc17496dc741dce97b83fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20W=C3=BCrbach?= Date: Thu, 15 Feb 2024 12:23:10 +0100 Subject: [PATCH 07/82] feat(scaffolder-backend-module-github): support oidc customization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Johannes Würbach --- .changeset/funny-meals-tease.md | 5 +++ .../api-report.md | 12 +++++++ .../src/actions/github.test.ts | 35 +++++++++++++++++++ .../src/actions/github.ts | 7 ++++ .../src/actions/githubRepoCreate.test.ts | 35 +++++++++++++++++++ .../src/actions/githubRepoCreate.ts | 7 ++++ .../src/actions/helpers.ts | 18 ++++++++++ .../src/actions/inputProperties.ts | 23 ++++++++++++ 8 files changed, 142 insertions(+) create mode 100644 .changeset/funny-meals-tease.md diff --git a/.changeset/funny-meals-tease.md b/.changeset/funny-meals-tease.md new file mode 100644 index 0000000000..3dce739952 --- /dev/null +++ b/.changeset/funny-meals-tease.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-github': minor +--- + +support oidc customization diff --git a/plugins/scaffolder-backend-module-github/api-report.md b/plugins/scaffolder-backend-module-github/api-report.md index a588840585..de03894a5a 100644 --- a/plugins/scaffolder-backend-module-github/api-report.md +++ b/plugins/scaffolder-backend-module-github/api-report.md @@ -205,6 +205,12 @@ export function createGithubRepoCreateAction(options: { [key: string]: string; } | undefined; + oidcCustomization?: + | { + useDefault: boolean; + includeClaimKeys?: string[] | undefined; + } + | undefined; requireCommitSigning?: boolean | undefined; }, JsonObject @@ -352,6 +358,12 @@ export function createPublishGithubAction(options: { [key: string]: string; } | undefined; + oidcCustomization?: + | { + useDefault: boolean; + includeClaimKeys?: string[] | undefined; + } + | undefined; requiredCommitSigning?: boolean | undefined; }, JsonObject diff --git a/plugins/scaffolder-backend-module-github/src/actions/github.test.ts b/plugins/scaffolder-backend-module-github/src/actions/github.test.ts index a2a8e11e15..75d9b74a8b 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/github.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/github.test.ts @@ -77,6 +77,7 @@ const mockOctokit = { getRepoPublicKey: jest.fn(), }, }, + request: jest.fn(), }; jest.mock('octokit', () => ({ Octokit: class { @@ -930,6 +931,40 @@ describe('publish:github', () => { }); }); + it('should configure oidc customizations when provided', async () => { + mockOctokit.rest.users.getByUsername.mockResolvedValue({ + data: { type: 'User' }, + }); + + mockOctokit.rest.repos.createForAuthenticatedUser.mockResolvedValue({ + data: { + clone_url: 'https://github.com/clone/url.git', + html_url: 'https://github.com/html/url', + }, + }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + oidcCustomization: { + useDefault: false, + includeClaimKeys: ['foo', 'bar'], + }, + }, + }); + + expect(mockOctokit.request).toHaveBeenCalledWith( + 'PUT /repos/{owner}/{repo}/actions/oidc/customization/sub', + { + include_claim_keys: ['foo', 'bar'], + owner: 'owner', + repo: 'repo', + use_default: false, + }, + ); + }); + it('should call output with the remoteUrl and the repoContentsUrl', async () => { mockOctokit.rest.users.getByUsername.mockResolvedValue({ data: { type: 'User' }, diff --git a/plugins/scaffolder-backend-module-github/src/actions/github.ts b/plugins/scaffolder-backend-module-github/src/actions/github.ts index 91d7a34aea..f32b65bc9a 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/github.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/github.ts @@ -109,6 +109,10 @@ export function createPublishGithubAction(options: { topics?: string[]; repoVariables?: { [key: string]: string }; secrets?: { [key: string]: string }; + oidcCustomization?: { + useDefault: boolean; + includeClaimKeys?: string[]; + }; requiredCommitSigning?: boolean; }>({ id: 'publish:github', @@ -156,6 +160,7 @@ export function createPublishGithubAction(options: { topics: inputProps.topics, repoVariables: inputProps.repoVariables, secrets: inputProps.secrets, + oidcCustomization: inputProps.oidcCustomization, requiredCommitSigning: inputProps.requiredCommitSigning, }, }, @@ -203,6 +208,7 @@ export function createPublishGithubAction(options: { topics, repoVariables, secrets, + oidcCustomization, token: providedToken, requiredCommitSigning = false, } = ctx.input; @@ -243,6 +249,7 @@ export function createPublishGithubAction(options: { topics, repoVariables, secrets, + oidcCustomization, ctx.logger, ); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.test.ts index 4cb007275e..c72a969e96 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.test.ts @@ -58,6 +58,7 @@ const mockOctokit = { getRepoPublicKey: jest.fn(), }, }, + request: jest.fn(), }; jest.mock('octokit', () => ({ Octokit: class { @@ -652,6 +653,40 @@ describe('github:repo:create', () => { }); }); + it('should configure oidc customizations when provided', async () => { + mockOctokit.rest.users.getByUsername.mockResolvedValue({ + data: { type: 'User' }, + }); + + mockOctokit.rest.repos.createForAuthenticatedUser.mockResolvedValue({ + data: { + clone_url: 'https://github.com/clone/url.git', + html_url: 'https://github.com/html/url', + }, + }); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + oidcCustomization: { + useDefault: false, + includeClaimKeys: ['foo', 'bar'], + }, + }, + }); + + expect(mockOctokit.request).toHaveBeenCalledWith( + 'PUT /repos/{owner}/{repo}/actions/oidc/customization/sub', + { + include_claim_keys: ['foo', 'bar'], + owner: 'owner', + repo: 'repo', + use_default: false, + }, + ); + }); + it('should call output with the remoteUrl', async () => { mockOctokit.rest.users.getByUsername.mockResolvedValue({ data: { type: 'User' }, diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.ts index 735919794f..52bf9be9c0 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.ts @@ -95,6 +95,10 @@ export function createGithubRepoCreateAction(options: { topics?: string[]; repoVariables?: { [key: string]: string }; secrets?: { [key: string]: string }; + oidcCustomization?: { + useDefault: boolean; + includeClaimKeys?: string[]; + }; requireCommitSigning?: boolean; }>({ id: 'github:repo:create', @@ -133,6 +137,7 @@ export function createGithubRepoCreateAction(options: { topics: inputProps.topics, repoVariables: inputProps.repoVariables, secrets: inputProps.secrets, + oidcCustomization: inputProps.oidcCustomization, requiredCommitSigning: inputProps.requiredCommitSigning, }, }, @@ -165,6 +170,7 @@ export function createGithubRepoCreateAction(options: { topics, repoVariables, secrets, + oidcCustomization, token: providedToken, } = ctx.input; @@ -204,6 +210,7 @@ export function createGithubRepoCreateAction(options: { topics, repoVariables, secrets, + oidcCustomization, ctx.logger, ); diff --git a/plugins/scaffolder-backend-module-github/src/actions/helpers.ts b/plugins/scaffolder-backend-module-github/src/actions/helpers.ts index 4d95a6494f..ec282c74d9 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/helpers.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/helpers.ts @@ -137,6 +137,12 @@ export async function createGithubRepoWithCollaboratorsAndTopics( topics: string[] | undefined, repoVariables: { [key: string]: string } | undefined, secrets: { [key: string]: string } | undefined, + oidcCustomization: + | { + useDefault: boolean; + includeClaimKeys?: string[]; + } + | undefined, logger: Logger, ) { // eslint-disable-next-line testing-library/no-await-sync-queries @@ -304,6 +310,18 @@ export async function createGithubRepoWithCollaboratorsAndTopics( } } + if (oidcCustomization) { + await client.request( + 'PUT /repos/{owner}/{repo}/actions/oidc/customization/sub', + { + owner, + repo, + use_default: oidcCustomization.useDefault, + include_claim_keys: oidcCustomization.includeClaimKeys, + }, + ); + } + return newRepo; } diff --git a/plugins/scaffolder-backend-module-github/src/actions/inputProperties.ts b/plugins/scaffolder-backend-module-github/src/actions/inputProperties.ts index 96e1f3b6e1..585526fe94 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/inputProperties.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/inputProperties.ts @@ -277,6 +277,28 @@ const secrets = { type: 'object', }; +const oidcCustomization = { + title: 'Repository OIDC customization template', + description: `OIDC customization template attached to the repository.`, + type: 'object', + additionalProperties: false, + properties: { + useDefault: { + title: 'Use Default', + type: 'boolean', + description: `Whether to use the default OIDC template or not.`, + }, + includeClaimKeys: { + title: 'Include claim keys', + type: 'array', + items: { + type: 'string', + }, + description: `Array of unique strings. Each claim key can only contain alphanumeric characters and underscores.`, + }, + }, +}; + export { access }; export { allowMergeCommit }; export { allowRebaseMerge }; @@ -313,3 +335,4 @@ export { topics }; export { requiredCommitSigning }; export { repoVariables }; export { secrets }; +export { oidcCustomization }; From 43b4e3500f8de50a80cfb189956f3a5688d0c337 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 14:05:46 +0100 Subject: [PATCH 08/82] beps/0003: service and rollout updates + move to implementable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Carl-Erik Bergström Co-authored-by: blam Co-authored-by: Camila Belo Signed-off-by: Patrik Oldsberg --- .../README.md | 80 ++++++++++++------- 1 file changed, 52 insertions(+), 28 deletions(-) diff --git a/beps/0003-auth-architecture-evolution/README.md b/beps/0003-auth-architecture-evolution/README.md index 713184be8c..4c11f1fc2a 100644 --- a/beps/0003-auth-architecture-evolution/README.md +++ b/beps/0003-auth-architecture-evolution/README.md @@ -1,6 +1,6 @@ --- title: Auth Architecture Evolution -status: provisional +status: implementable authors: - '@Rugvip' owners: @@ -60,6 +60,7 @@ The following goals are the primary focus of this BEP: - No advanced rate limiting or other protection against DDoS attacks. If this is a concern then adopters should still use other external technologies to protect access to their Backstage instance. - As part of the immediate work we will only add as much support for service-to-service auth as is needed for a stable API, and not necessarily make it very capable from the start. +- We will not aim to provide an abstraction that makes it possible to switch out the `Authorization` header for service-to-service communication. ## Proposal @@ -126,11 +127,13 @@ export interface AuthService { type: TType, ): credentials is BackstageCredentials; - getOwnCredentials(): Promise>; + getOwnServiceCredentials(): Promise< + BackstageCredentials + >; - // TODO: should the caller provide the target plugin ID? if not - probably skip the object form - issueServiceToken(options: { - forward: BackstageCredentials; + getPluginRequestToken(options: { + onBehalfOf: BackstageCredentials; + targetPluginId: string; }): Promise<{ token: string }>; } ``` @@ -257,7 +260,6 @@ The new `HttpAuthService` interface is defined as follows: ```ts type BackstageHttpAccessToPrincipalTypesMapping = { user: BackstageUserPrincipal; - 'user-cookie': BackstageUserPrincipal; service: BackstageServicePrincipal; unauthenticated: BackstageNonePrincipal; unknown: unknown; @@ -270,17 +272,16 @@ export interface HttpAuthService { | keyof BackstageHttpAccessToPrincipalTypesMapping = 'unknown', >( req: Request, - options?: { allow: Array }, + options?: { + allow?: Array; + allowedAuthMethods?: Array<'token' | 'cookie'>; + }, ): Promise< BackstageCredentials >; - requestHeaders(options: { - forward: BackstageCredentials; - }): Promise>; - // The cookie issued by this method must be consumable by the `credentials` method, which in turn - // should create a credentials object that can be passed to the `issueServiceToken` method. + // should create a credentials object that can be passed to the `getPluginRequestToken` method. // The issued token must then in turn be a valid token for a user principal with full access. issueUserCookie(res: Response): Promise; } @@ -304,6 +305,25 @@ router.get('/read-data', (req, res) => { }); ``` +#### Issue a service token for a backend-to-backend request + +NOTE: This is not what we want this kind of request to look like in practice. The goal is to forward credential objects as far as possible, keeping the `auth.getPluginRequestToken(...)` in API client code rather than plugin app code. + +```ts +const { token } = await auth.getPluginRequestToken({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: 'example', +}); + +const baseUrl = await discovery.getBaseUrl('example'); +const res = await fetch(`${baseUrl}/some-resource`, { + headers: { + // A utility may be provided for this in the future if needed, this is currently fairly rare + Authorization: `Bearer ${token}`, + }, +}); +``` + #### Forward the user credentials from an incoming requests to upstream plugin backend ```ts @@ -315,8 +335,9 @@ class CatalogIntegration { }, ) { return catalogClient.getEntityByRef(req.params.entityRef, { - token: await auth.issueServiceToken({ - forward: options.credentials, + token: await auth.getPluginRequestToken({ + onBehalfOf: options.credentials, + targetPluginId: 'catalog', }), }); } @@ -402,27 +423,30 @@ backend: dangerouslyDisableServiceAuth: true ``` -The exact impact that this has is that it disables the check in the `HttpRouterService` implementation, effectively applying the `unauthenticated` access level to all routes. Furthermore, it will also change `AuthService` so that the `issueServiceToken()` method will now issue an empty token for a `'none'` principal, rather than throwing. +The exact impact that this has is that it disables the check in the `HttpRouterService` implementation, effectively applying the `unauthenticated` access level to all routes. Furthermore, it will also change `AuthService` so that the `getPluginRequestToken()` method will now issue an empty token for a `'none'` principal, rather than throwing. ## Release Plan The existing `IdentityService` and `TokenManagerService` will be deprecated and instead implemented in terms of the new `AuthService`. -The release plan for the `HttpAuthService` is TBD, but is likely to be shipped as a no-op for plugins using the old backend system. The goal is for all plugins using the new backend system to have endpoint security be opt-out, which will be a breaking change. +The new `AuthService` and `HttpAuthService` will need backwards compatible implementations for the old backend system. The plan is to not apply any access restrictions for the old Backend system, only implementing that in the new system. The backwards compatibility helpers will use the provided `identity` and `tokenManager` services if available, and plugins should provide fallbacks in the same way as they currently do. If these are not provided, the `identity` client will fall back to `DefaultIdentityClient`, and `tokenManager` will fall back `ServicerTokenManager.noop()`. -### Implementation Tasks +The backwards compatibility helpers will have the following behavior for each individual service call: -- [ ] Implement `AuthService` -- [ ] Implement `HttpAuthService` - leave cookie auth as unimplemented for now -- [ ] Add `addAuthPolicy()` for `HttpRouterService`, using `HttpAuthService` -- [ ] Implement a compatibility wrapper in `backend-common` that accepts `AuthService`, `HttpAuthService`, `IdentityService`, and `TokenManagerService` (all optional), and returns implementations for `AuthService` and `HttpAuthService`, such hat existing plugins can use a single `createRouter` implementation for both the old and new backend systems. -- [ ] Implement `UserInfoService` in `@backstage/auth-node` - for now it will just extract the ownership entity refs from the token stored in the credentials -- [ ] Implement cookie auth in `HttpAuthService` - just put the user token in the cookie for now -- [ ] Deprecate `IdentityService` and `TokenManagerService`, switch to using default factories that depend on the `AuthService` and `HttpAuthService`. Stop supplying implementations for these in `backend-defaults` and `backend-test-utils` -- [ ] Migrate plugins: - - [ ] Permission backend - - [ ] TechDocs backend - - [ ] App backend +- `auth.authenticate(token)`: If the decoded token has the `backstage` audience, authenticate the token for a user principal using `identity.getIdentity(...)`, otherwise authenticate it using `tokenManager.authenticate(...)` and return a service principal with the subject `external:backstage-plugin`. If a no-op token manager is used then anything but a user token will be treated as a valid service token, which is consistent with existing behavior. +- `auth.getOwnServiceCredentials()`: Use original implementation. +- `auth.isPrincipal()`: Use original implementation. +- `auth.getPluginRequestToken(options)`: Same behavior as the original implementation, using the `tokenManager` to issue service tokens, with the exception that a `none` principal will translate to an empty token rather than an error in order to properly forward calls with a no-op token manager. +- `httpAuth.credentials(...)`: Use original implementation. +- `httpAuth.issueUserCookie(...)`: This is a no-op as we do not need to support cookie auth in the legacy adapter. + +With this compatibility layer in place all plugins will be refactored to always use the new `AuthService` and `HttpAuthService` internally. The old deprecated services are only accepted at the public API boundaries, i.e. `createRouter` and similar. All plugin code beyond that point uses the new services. + +We do not roll out support for the new auth services for the old backend system, the full implementation is only supported in the new backend system. In particular this means that the new default protection in the `HttpRouterService` only apply to the new backend system. + +Users of the old backend system may already have their own protection set up, which we need to take into account, ensuring that we do not break these existing implementations. + +Several API clients will be updated to support passing `BackstageCredentials` instead of a token, although it is not a requirement to update all clients. In particular we hold of on migration isomorphic clients, leaving them to keep consuming tokens where possible. Adding support for credentials to be passed to these clients is a separate future improvement. ## Dependencies From d3dd64a90b211e74fca15bae1ed63d54a4f167f1 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 14:37:04 +0100 Subject: [PATCH 09/82] catalog-backend-module-unprocessed: refactor for forwards compatibility Signed-off-by: Patrik Oldsberg --- .changeset/clever-steaks-hope.md | 5 +++++ plugins/catalog-backend-module-unprocessed/api-report.md | 2 +- .../src/UnprocessedEntitiesModule.ts | 9 +-------- plugins/catalog-backend-module-unprocessed/src/types.ts | 1 - 4 files changed, 7 insertions(+), 10 deletions(-) create mode 100644 .changeset/clever-steaks-hope.md diff --git a/.changeset/clever-steaks-hope.md b/.changeset/clever-steaks-hope.md new file mode 100644 index 0000000000..94c6e8ee29 --- /dev/null +++ b/.changeset/clever-steaks-hope.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-unprocessed': patch +--- + +Explicitly only depend on the `use` method from the `HttpRouterService`. diff --git a/plugins/catalog-backend-module-unprocessed/api-report.md b/plugins/catalog-backend-module-unprocessed/api-report.md index 6e5e4f843b..569bd572da 100644 --- a/plugins/catalog-backend-module-unprocessed/api-report.md +++ b/plugins/catalog-backend-module-unprocessed/api-report.md @@ -13,7 +13,7 @@ export default catalogModuleUnprocessedEntities; // @public export class UnprocessedEntitiesModule { - constructor(database: Knex, router: HttpRouterService); + constructor(database: Knex, router: Pick); // (undocumented) registerRoutes(): void; } diff --git a/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts b/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts index bdd3f64488..a01f717e12 100644 --- a/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts +++ b/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts @@ -23,7 +23,6 @@ import { import { Knex } from 'knex'; import { HttpRouterService } from '@backstage/backend-plugin-api'; import Router from 'express-promise-router'; -import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; /** * Module providing Unprocessed Entities API endpoints @@ -35,7 +34,7 @@ export class UnprocessedEntitiesModule { constructor( private readonly database: Knex, - private readonly router: HttpRouterService, + private readonly router: Pick, ) { this.moduleRouter = Router(); this.router.use(this.moduleRouter); @@ -111,9 +110,6 @@ export class UnprocessedEntitiesModule { await this.unprocessed({ reason: 'failed', owner: req.query.owner as string, - authorizationToken: getBearerTokenFromAuthorizationHeader( - req.header('authorization'), - ), }), ); }) @@ -122,9 +118,6 @@ export class UnprocessedEntitiesModule { await this.unprocessed({ reason: 'pending', owner: req.query.owner as string, - authorizationToken: getBearerTokenFromAuthorizationHeader( - req.header('authorization'), - ), }), ); }); diff --git a/plugins/catalog-backend-module-unprocessed/src/types.ts b/plugins/catalog-backend-module-unprocessed/src/types.ts index 8d70345682..099412444b 100644 --- a/plugins/catalog-backend-module-unprocessed/src/types.ts +++ b/plugins/catalog-backend-module-unprocessed/src/types.ts @@ -60,7 +60,6 @@ export type RefreshStateError = { export interface UnprocessedEntitiesRequest { reason: 'failed' | 'pending'; owner?: string; - authorizationToken?: string; } export interface UnprocessedEntitiesResponse { From 01eedbbc8cdc6acf0ff617ac78000145b32e0a98 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 14:46:20 +0000 Subject: [PATCH 10/82] fix(deps): update dependency isomorphic-git to v1.25.4 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6280775f8b..f67b1a56a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -31570,8 +31570,8 @@ __metadata: linkType: hard "isomorphic-git@npm:^1.23.0": - version: 1.25.3 - resolution: "isomorphic-git@npm:1.25.3" + version: 1.25.4 + resolution: "isomorphic-git@npm:1.25.4" dependencies: async-lock: ^1.1.0 clean-git-ref: ^2.0.1 @@ -31586,7 +31586,7 @@ __metadata: simple-get: ^4.0.1 bin: isogit: cli.cjs - checksum: 747da1bd0435898a02f8c1ba07ce66c704ea311338b66a44830a5ce1fe9a256a3ea1ec9be5baa087f88134aa686b5d0c6dc2b9338b1fd523f2869ef2480e4d4e + checksum: 86ed42b7d15db04af5a1918b7cf50153e688a2aabd5d77a6a5f2a1798bb476aef265edd3bb3d80058929d70cd0c23247074760a48720bbba9e76b044881e6d6c languageName: node linkType: hard From 468f51100cdac1446682064b6cc78acc39778757 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 16:03:09 +0100 Subject: [PATCH 11/82] Update beps/0003-auth-architecture-evolution/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Patrik Oldsberg --- beps/0003-auth-architecture-evolution/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beps/0003-auth-architecture-evolution/README.md b/beps/0003-auth-architecture-evolution/README.md index 4c11f1fc2a..92e27e06e6 100644 --- a/beps/0003-auth-architecture-evolution/README.md +++ b/beps/0003-auth-architecture-evolution/README.md @@ -429,7 +429,7 @@ The exact impact that this has is that it disables the check in the `HttpRouterS The existing `IdentityService` and `TokenManagerService` will be deprecated and instead implemented in terms of the new `AuthService`. -The new `AuthService` and `HttpAuthService` will need backwards compatible implementations for the old backend system. The plan is to not apply any access restrictions for the old Backend system, only implementing that in the new system. The backwards compatibility helpers will use the provided `identity` and `tokenManager` services if available, and plugins should provide fallbacks in the same way as they currently do. If these are not provided, the `identity` client will fall back to `DefaultIdentityClient`, and `tokenManager` will fall back `ServicerTokenManager.noop()`. +The new `AuthService` and `HttpAuthService` will need backwards compatible implementations for the old backend system. The plan is to not apply any access restrictions for the old Backend system, only implementing that in the new system. The backwards compatibility helpers will use the provided `identity` and `tokenManager` services if available, and plugins should provide fallbacks in the same way as they currently do. If these are not provided, the `identity` client will fall back to `DefaultIdentityClient`, and `tokenManager` will fall back to `ServicerTokenManager.noop()`. The backwards compatibility helpers will have the following behavior for each individual service call: From 16951f707b544524338716d266f44be5b1345183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 15 Feb 2024 16:08:45 +0100 Subject: [PATCH 12/82] do not pin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .github/renovate.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 139e8ce8a2..5d979d5f22 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -9,7 +9,7 @@ 'default:pinDigestsDisabled', ], // do not pin dev dependencies, which are part of the best-practices preset - ignorePresets: [':pinDevDependencies'], + ignorePresets: [':pinDevDependencies', ':pinDigest'], // the default limit are 10 PRs prConcurrentLimit: 20, From 213de53ef2d0a48896d530f03ab745dfc0178103 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:26:18 +0000 Subject: [PATCH 13/82] chore(deps): update dependency webpack to v5.90.2 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- storybook/yarn.lock | 6 +++--- yarn.lock | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/storybook/yarn.lock b/storybook/yarn.lock index 42453e2080..e59970f4f7 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -11756,8 +11756,8 @@ __metadata: linkType: hard "webpack@npm:^5.73.0": - version: 5.90.1 - resolution: "webpack@npm:5.90.1" + version: 5.90.2 + resolution: "webpack@npm:5.90.2" dependencies: "@types/eslint-scope": ^3.7.3 "@types/estree": ^1.0.5 @@ -11788,7 +11788,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: a7be844d5720a0c6282fec012e6fa34b1137dff953c5d48bf2ef066a6c27c1dbc92a9b9effc05ee61c9fe269499266db9782073f2d82a589d3c5c966ffc56584 + checksum: 4af55f314c3610e0b17afd01960c4cf9d8d90c87a58ef7d7dc7a0a019f48e2bba4eff63b02d9da56fc61df5b04af0d66b3fa4ec82937a780d37a64db84c643fe languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index 6280775f8b..926e693d07 100644 --- a/yarn.lock +++ b/yarn.lock @@ -45676,8 +45676,8 @@ __metadata: linkType: hard "webpack@npm:^5, webpack@npm:^5.70.0": - version: 5.90.1 - resolution: "webpack@npm:5.90.1" + version: 5.90.2 + resolution: "webpack@npm:5.90.2" dependencies: "@types/eslint-scope": ^3.7.3 "@types/estree": ^1.0.5 @@ -45708,7 +45708,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: a7be844d5720a0c6282fec012e6fa34b1137dff953c5d48bf2ef066a6c27c1dbc92a9b9effc05ee61c9fe269499266db9782073f2d82a589d3c5c966ffc56584 + checksum: 4af55f314c3610e0b17afd01960c4cf9d8d90c87a58ef7d7dc7a0a019f48e2bba4eff63b02d9da56fc61df5b04af0d66b3fa4ec82937a780d37a64db84c643fe languageName: node linkType: hard From 7634060fb231ac4fe52c7899cb37037d2b9b8078 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:27:14 +0000 Subject: [PATCH 14/82] fix(deps): update dependency swagger-ui-react to v5.11.6 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6280775f8b..c5c1321537 100644 --- a/yarn.lock +++ b/yarn.lock @@ -43237,8 +43237,8 @@ __metadata: linkType: hard "swagger-ui-react@npm:^5.0.0": - version: 5.11.4 - resolution: "swagger-ui-react@npm:5.11.4" + version: 5.11.6 + resolution: "swagger-ui-react@npm:5.11.6" dependencies: "@babel/runtime-corejs3": ^7.23.9 "@braintree/sanitize-url": =7.0.0 @@ -43277,7 +43277,7 @@ __metadata: peerDependencies: react: ">=16.8.0 <19" react-dom: ">=16.8.0 <19" - checksum: 080a367c28019e20193887a6a1dc70d42c030e2b489c9099b60f4a0cb7ebc4779d0731703060f72022bc997d6e6811661f055514e1ace1454f3bc46bb8aceaa9 + checksum: 4556acd2fca69d5b0f7fd1592467818428611f7fce37aeea002c71604c3fdf5314425a99180f08ad257676eec80123cd9ac31e2576102ac9f9fb5f420cb5bbf4 languageName: node linkType: hard From cf59dc40b9c21dc22ceffba0083a0bc80539cac1 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 15 Feb 2024 17:17:16 +0100 Subject: [PATCH 15/82] Update beps/0003-auth-architecture-evolution/README.md Co-authored-by: Phil Kuang Signed-off-by: Patrik Oldsberg --- beps/0003-auth-architecture-evolution/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beps/0003-auth-architecture-evolution/README.md b/beps/0003-auth-architecture-evolution/README.md index 92e27e06e6..dc475fa14d 100644 --- a/beps/0003-auth-architecture-evolution/README.md +++ b/beps/0003-auth-architecture-evolution/README.md @@ -446,7 +446,7 @@ We do not roll out support for the new auth services for the old backend system, Users of the old backend system may already have their own protection set up, which we need to take into account, ensuring that we do not break these existing implementations. -Several API clients will be updated to support passing `BackstageCredentials` instead of a token, although it is not a requirement to update all clients. In particular we hold of on migration isomorphic clients, leaving them to keep consuming tokens where possible. Adding support for credentials to be passed to these clients is a separate future improvement. +Several API clients will be updated to support passing `BackstageCredentials` instead of a token, although it is not a requirement to update all clients. In particular we will hold off on migrating isomorphic clients, leaving them to keep consuming tokens where possible. Adding support for credentials to be passed to these clients is a separate future improvement. ## Dependencies From bf3da1642c1309428a957571ba5cd0aef3c38a61 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 16:12:27 +0000 Subject: [PATCH 16/82] fix(deps): update dependency typescript-json-schema to ^0.63.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .changeset/renovate-4b0ba1e.md | 5 +++++ packages/config-loader/package.json | 2 +- yarn.lock | 10 +++++----- 3 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 .changeset/renovate-4b0ba1e.md diff --git a/.changeset/renovate-4b0ba1e.md b/.changeset/renovate-4b0ba1e.md new file mode 100644 index 0000000000..54dcd58187 --- /dev/null +++ b/.changeset/renovate-4b0ba1e.md @@ -0,0 +1,5 @@ +--- +'@backstage/config-loader': patch +--- + +Updated dependency `typescript-json-schema` to `^0.63.0`. diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index a9e80a4672..f5ed8e4d85 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -47,7 +47,7 @@ "lodash": "^4.17.21", "minimist": "^1.2.5", "node-fetch": "^2.6.7", - "typescript-json-schema": "^0.62.0", + "typescript-json-schema": "^0.63.0", "yaml": "^2.0.0" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index d735732949..3bff269402 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3775,7 +3775,7 @@ __metadata: minimist: ^1.2.5 msw: ^1.0.0 node-fetch: ^2.6.7 - typescript-json-schema: ^0.62.0 + typescript-json-schema: ^0.63.0 yaml: ^2.0.0 zen-observable: ^0.10.0 languageName: unknown @@ -44336,9 +44336,9 @@ __metadata: languageName: node linkType: hard -"typescript-json-schema@npm:^0.62.0": - version: 0.62.0 - resolution: "typescript-json-schema@npm:0.62.0" +"typescript-json-schema@npm:^0.63.0": + version: 0.63.0 + resolution: "typescript-json-schema@npm:0.63.0" dependencies: "@types/json-schema": ^7.0.9 "@types/node": ^16.9.2 @@ -44350,7 +44350,7 @@ __metadata: yargs: ^17.1.1 bin: typescript-json-schema: bin/typescript-json-schema - checksum: 0b0ba8f86456e7bd0b2d35d3c74a6cb72b168e779352398956d4f237eff011ec2a30b0ab1b3932bd5ceab99e1ea7bc6cc7158e49d49f24daeaf11771c27c7771 + checksum: 619ab7aece08e140ba9542c6378c335751dbff3994a23343d0af67786a0c1e682d532a436c1674ddb10bca3f34972ecac7ba529b66d0e9b3e00ca81defb3aa77 languageName: node linkType: hard From 86fa9cce6e8b161db894f848bfcc70cb9c44364c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 16:56:13 +0000 Subject: [PATCH 17/82] chore(deps): update github/codeql-action action to v3.24.3 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- .github/workflows/sync_snyk-monitor.yml | 2 +- .github/workflows/verify_codeql.yml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 4155f08e03..621776d69b 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -66,6 +66,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@e675ced7a7522a761fc9c8eb26682c8b27c42b2b # v3.24.1 + uses: github/codeql-action/upload-sarif@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3 with: sarif_file: results.sarif diff --git a/.github/workflows/sync_snyk-monitor.yml b/.github/workflows/sync_snyk-monitor.yml index 080bd3cc73..7ee4e72d38 100644 --- a/.github/workflows/sync_snyk-monitor.yml +++ b/.github/workflows/sync_snyk-monitor.yml @@ -58,6 +58,6 @@ jobs: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} NODE_OPTIONS: --max-old-space-size=7168 - name: Upload Snyk report - uses: github/codeql-action/upload-sarif@e675ced7a7522a761fc9c8eb26682c8b27c42b2b # v3.24.1 + uses: github/codeql-action/upload-sarif@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3 with: sarif_file: snyk.sarif diff --git a/.github/workflows/verify_codeql.yml b/.github/workflows/verify_codeql.yml index 48195726e1..7c7ef286db 100644 --- a/.github/workflows/verify_codeql.yml +++ b/.github/workflows/verify_codeql.yml @@ -55,7 +55,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@e675ced7a7522a761fc9c8eb26682c8b27c42b2b # v3.24.1 + uses: github/codeql-action/init@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -66,7 +66,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@e675ced7a7522a761fc9c8eb26682c8b27c42b2b # v3.24.1 + uses: github/codeql-action/autobuild@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -80,4 +80,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e675ced7a7522a761fc9c8eb26682c8b27c42b2b # v3.24.1 + uses: github/codeql-action/analyze@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3 From 603a9729960098772ce12be1c230d527dcfbfa66 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 21:38:34 +0000 Subject: [PATCH 18/82] fix(deps): update aws-sdk-js-v3 monorepo to v3.515.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 588 +++++++++++++++++++++++++++--------------------------- 1 file changed, 294 insertions(+), 294 deletions(-) diff --git a/yarn.lock b/yarn.lock index d735732949..c14cb29002 100644 --- a/yarn.lock +++ b/yarn.lock @@ -363,24 +363,24 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-cognito-identity@npm:3.514.0": - version: 3.514.0 - resolution: "@aws-sdk/client-cognito-identity@npm:3.514.0" +"@aws-sdk/client-cognito-identity@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/client-cognito-identity@npm:3.515.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.513.0 + "@aws-sdk/client-sts": 3.515.0 "@aws-sdk/core": 3.513.0 - "@aws-sdk/credential-provider-node": 3.514.0 - "@aws-sdk/middleware-host-header": 3.511.0 - "@aws-sdk/middleware-logger": 3.511.0 - "@aws-sdk/middleware-recursion-detection": 3.511.0 - "@aws-sdk/middleware-user-agent": 3.511.0 - "@aws-sdk/region-config-resolver": 3.511.0 - "@aws-sdk/types": 3.511.0 - "@aws-sdk/util-endpoints": 3.511.0 - "@aws-sdk/util-user-agent-browser": 3.511.0 - "@aws-sdk/util-user-agent-node": 3.511.0 + "@aws-sdk/credential-provider-node": 3.515.0 + "@aws-sdk/middleware-host-header": 3.515.0 + "@aws-sdk/middleware-logger": 3.515.0 + "@aws-sdk/middleware-recursion-detection": 3.515.0 + "@aws-sdk/middleware-user-agent": 3.515.0 + "@aws-sdk/region-config-resolver": 3.515.0 + "@aws-sdk/types": 3.515.0 + "@aws-sdk/util-endpoints": 3.515.0 + "@aws-sdk/util-user-agent-browser": 3.515.0 + "@aws-sdk/util-user-agent-node": 3.515.0 "@smithy/config-resolver": ^2.1.1 "@smithy/core": ^1.3.2 "@smithy/fetch-http-handler": ^2.4.1 @@ -407,28 +407,28 @@ __metadata: "@smithy/util-retry": ^2.1.1 "@smithy/util-utf8": ^2.1.1 tslib: ^2.5.0 - checksum: 38629787a3dbbaf7edad47c7e76c3b5015b20c7e9e8cbb343f5050f3c7bd31920e22e45e1ccbf21fe9fe331dc8f307420e5da6b5c5f0d26e1ee77e6a5dddd86a + checksum: e254357719b355a7c6cdd718c3896aca9971ea9479887c221841ec2c6e91f15b880f6a5d1ebfc62af223b4d02a0d4a882aa8394b436f9b544658ee87a481e1ac languageName: node linkType: hard "@aws-sdk/client-eks@npm:^3.350.0": - version: 3.514.0 - resolution: "@aws-sdk/client-eks@npm:3.514.0" + version: 3.515.0 + resolution: "@aws-sdk/client-eks@npm:3.515.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.513.0 + "@aws-sdk/client-sts": 3.515.0 "@aws-sdk/core": 3.513.0 - "@aws-sdk/credential-provider-node": 3.514.0 - "@aws-sdk/middleware-host-header": 3.511.0 - "@aws-sdk/middleware-logger": 3.511.0 - "@aws-sdk/middleware-recursion-detection": 3.511.0 - "@aws-sdk/middleware-user-agent": 3.511.0 - "@aws-sdk/region-config-resolver": 3.511.0 - "@aws-sdk/types": 3.511.0 - "@aws-sdk/util-endpoints": 3.511.0 - "@aws-sdk/util-user-agent-browser": 3.511.0 - "@aws-sdk/util-user-agent-node": 3.511.0 + "@aws-sdk/credential-provider-node": 3.515.0 + "@aws-sdk/middleware-host-header": 3.515.0 + "@aws-sdk/middleware-logger": 3.515.0 + "@aws-sdk/middleware-recursion-detection": 3.515.0 + "@aws-sdk/middleware-user-agent": 3.515.0 + "@aws-sdk/region-config-resolver": 3.515.0 + "@aws-sdk/types": 3.515.0 + "@aws-sdk/util-endpoints": 3.515.0 + "@aws-sdk/util-user-agent-browser": 3.515.0 + "@aws-sdk/util-user-agent-node": 3.515.0 "@smithy/config-resolver": ^2.1.1 "@smithy/core": ^1.3.2 "@smithy/fetch-http-handler": ^2.4.1 @@ -456,29 +456,29 @@ __metadata: "@smithy/util-utf8": ^2.1.1 "@smithy/util-waiter": ^2.1.1 tslib: ^2.5.0 - uuid: ^8.3.2 - checksum: 83ba19700e9c00c2035239c9fca710177d67eb7ee568ddafe256b40ca4724d0a1de4426c3bc5b9c66ba365206351eaf931ec4988b8dd44e17a42f8afdf84b0e3 + uuid: ^9.0.1 + checksum: 38366b504f5cda083637801b8a89cb03fb05fca56e6266a18d4fa4772a5556a461efcb82c8ed9690d8ba4c49e2ec2bdd71c7d3f987d2e7a85506439de2199ff6 languageName: node linkType: hard "@aws-sdk/client-organizations@npm:^3.350.0": - version: 3.514.0 - resolution: "@aws-sdk/client-organizations@npm:3.514.0" + version: 3.515.0 + resolution: "@aws-sdk/client-organizations@npm:3.515.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.513.0 + "@aws-sdk/client-sts": 3.515.0 "@aws-sdk/core": 3.513.0 - "@aws-sdk/credential-provider-node": 3.514.0 - "@aws-sdk/middleware-host-header": 3.511.0 - "@aws-sdk/middleware-logger": 3.511.0 - "@aws-sdk/middleware-recursion-detection": 3.511.0 - "@aws-sdk/middleware-user-agent": 3.511.0 - "@aws-sdk/region-config-resolver": 3.511.0 - "@aws-sdk/types": 3.511.0 - "@aws-sdk/util-endpoints": 3.511.0 - "@aws-sdk/util-user-agent-browser": 3.511.0 - "@aws-sdk/util-user-agent-node": 3.511.0 + "@aws-sdk/credential-provider-node": 3.515.0 + "@aws-sdk/middleware-host-header": 3.515.0 + "@aws-sdk/middleware-logger": 3.515.0 + "@aws-sdk/middleware-recursion-detection": 3.515.0 + "@aws-sdk/middleware-user-agent": 3.515.0 + "@aws-sdk/region-config-resolver": 3.515.0 + "@aws-sdk/types": 3.515.0 + "@aws-sdk/util-endpoints": 3.515.0 + "@aws-sdk/util-user-agent-browser": 3.515.0 + "@aws-sdk/util-user-agent-node": 3.515.0 "@smithy/config-resolver": ^2.1.1 "@smithy/core": ^1.3.2 "@smithy/fetch-http-handler": ^2.4.1 @@ -505,37 +505,37 @@ __metadata: "@smithy/util-retry": ^2.1.1 "@smithy/util-utf8": ^2.1.1 tslib: ^2.5.0 - checksum: bf8e4b074eb061b76307c116b0d328de48473d0b52c338b8d179f6e710fd7c387001ef1c3dde6278c70963711e55e6b13579407e17c78222ea51dec378b8eca4 + checksum: 4b947f1fc5ca196b007855cc5d75accb82825adfe4dea370d181b9605bfe827ddc0f6cb073d7ef7f768a523be4e393a2dc1e28a999d118bda050f354997e8f60 languageName: node linkType: hard "@aws-sdk/client-s3@npm:^3.350.0": - version: 3.514.0 - resolution: "@aws-sdk/client-s3@npm:3.514.0" + version: 3.515.0 + resolution: "@aws-sdk/client-s3@npm:3.515.0" dependencies: "@aws-crypto/sha1-browser": 3.0.0 "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.513.0 + "@aws-sdk/client-sts": 3.515.0 "@aws-sdk/core": 3.513.0 - "@aws-sdk/credential-provider-node": 3.514.0 - "@aws-sdk/middleware-bucket-endpoint": 3.511.0 - "@aws-sdk/middleware-expect-continue": 3.511.0 - "@aws-sdk/middleware-flexible-checksums": 3.511.0 - "@aws-sdk/middleware-host-header": 3.511.0 - "@aws-sdk/middleware-location-constraint": 3.511.0 - "@aws-sdk/middleware-logger": 3.511.0 - "@aws-sdk/middleware-recursion-detection": 3.511.0 - "@aws-sdk/middleware-sdk-s3": 3.511.0 - "@aws-sdk/middleware-signing": 3.511.0 - "@aws-sdk/middleware-ssec": 3.511.0 - "@aws-sdk/middleware-user-agent": 3.511.0 - "@aws-sdk/region-config-resolver": 3.511.0 - "@aws-sdk/signature-v4-multi-region": 3.511.0 - "@aws-sdk/types": 3.511.0 - "@aws-sdk/util-endpoints": 3.511.0 - "@aws-sdk/util-user-agent-browser": 3.511.0 - "@aws-sdk/util-user-agent-node": 3.511.0 + "@aws-sdk/credential-provider-node": 3.515.0 + "@aws-sdk/middleware-bucket-endpoint": 3.515.0 + "@aws-sdk/middleware-expect-continue": 3.515.0 + "@aws-sdk/middleware-flexible-checksums": 3.515.0 + "@aws-sdk/middleware-host-header": 3.515.0 + "@aws-sdk/middleware-location-constraint": 3.515.0 + "@aws-sdk/middleware-logger": 3.515.0 + "@aws-sdk/middleware-recursion-detection": 3.515.0 + "@aws-sdk/middleware-sdk-s3": 3.515.0 + "@aws-sdk/middleware-signing": 3.515.0 + "@aws-sdk/middleware-ssec": 3.515.0 + "@aws-sdk/middleware-user-agent": 3.515.0 + "@aws-sdk/region-config-resolver": 3.515.0 + "@aws-sdk/signature-v4-multi-region": 3.515.0 + "@aws-sdk/types": 3.515.0 + "@aws-sdk/util-endpoints": 3.515.0 + "@aws-sdk/util-user-agent-browser": 3.515.0 + "@aws-sdk/util-user-agent-node": 3.515.0 "@aws-sdk/xml-builder": 3.496.0 "@smithy/config-resolver": ^2.1.1 "@smithy/core": ^1.3.2 @@ -571,29 +571,29 @@ __metadata: "@smithy/util-waiter": ^2.1.1 fast-xml-parser: 4.2.5 tslib: ^2.5.0 - checksum: 2a5b1da2343825c9e44d764d63e0be800dee5a51b26804daa6a57de12c6d9514a49a3673804a303f45d3a66d657ef8518ed186ceb205738e1794a81c224dc2be + checksum: f61f91fb45500108520357e61a018975f4e4a49df378fa16ad0fc15b59560bdfcc11c6cb7d95ad1c4b6e0607e99788662e4013d8d529af75a36dffa5c8bfe5ca languageName: node linkType: hard "@aws-sdk/client-sqs@npm:^3.350.0": - version: 3.514.0 - resolution: "@aws-sdk/client-sqs@npm:3.514.0" + version: 3.515.0 + resolution: "@aws-sdk/client-sqs@npm:3.515.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.513.0 + "@aws-sdk/client-sts": 3.515.0 "@aws-sdk/core": 3.513.0 - "@aws-sdk/credential-provider-node": 3.514.0 - "@aws-sdk/middleware-host-header": 3.511.0 - "@aws-sdk/middleware-logger": 3.511.0 - "@aws-sdk/middleware-recursion-detection": 3.511.0 - "@aws-sdk/middleware-sdk-sqs": 3.511.0 - "@aws-sdk/middleware-user-agent": 3.511.0 - "@aws-sdk/region-config-resolver": 3.511.0 - "@aws-sdk/types": 3.511.0 - "@aws-sdk/util-endpoints": 3.511.0 - "@aws-sdk/util-user-agent-browser": 3.511.0 - "@aws-sdk/util-user-agent-node": 3.511.0 + "@aws-sdk/credential-provider-node": 3.515.0 + "@aws-sdk/middleware-host-header": 3.515.0 + "@aws-sdk/middleware-logger": 3.515.0 + "@aws-sdk/middleware-recursion-detection": 3.515.0 + "@aws-sdk/middleware-sdk-sqs": 3.515.0 + "@aws-sdk/middleware-user-agent": 3.515.0 + "@aws-sdk/region-config-resolver": 3.515.0 + "@aws-sdk/types": 3.515.0 + "@aws-sdk/util-endpoints": 3.515.0 + "@aws-sdk/util-user-agent-browser": 3.515.0 + "@aws-sdk/util-user-agent-node": 3.515.0 "@smithy/config-resolver": ^2.1.1 "@smithy/core": ^1.3.2 "@smithy/fetch-http-handler": ^2.4.1 @@ -621,27 +621,27 @@ __metadata: "@smithy/util-retry": ^2.1.1 "@smithy/util-utf8": ^2.1.1 tslib: ^2.5.0 - checksum: b1ab3853441f3a2e9235e3a8594b9c2496c777331da12c82ade6ce267c7839c6fa60a7e9c1c23a7ad55fca357d7c1a47c1b3b6a1512312f65a02908537be7eb9 + checksum: e92bbea7c7453cee74898ffde1092437693eb19b3a623243913805229ab6b1ec7905735a2dd58476915d574beeca2675f00eb89b5de8c3f099becc68c9ade901 languageName: node linkType: hard -"@aws-sdk/client-sso-oidc@npm:3.513.0": - version: 3.513.0 - resolution: "@aws-sdk/client-sso-oidc@npm:3.513.0" +"@aws-sdk/client-sso-oidc@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/client-sso-oidc@npm:3.515.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.513.0 + "@aws-sdk/client-sts": 3.515.0 "@aws-sdk/core": 3.513.0 - "@aws-sdk/middleware-host-header": 3.511.0 - "@aws-sdk/middleware-logger": 3.511.0 - "@aws-sdk/middleware-recursion-detection": 3.511.0 - "@aws-sdk/middleware-user-agent": 3.511.0 - "@aws-sdk/region-config-resolver": 3.511.0 - "@aws-sdk/types": 3.511.0 - "@aws-sdk/util-endpoints": 3.511.0 - "@aws-sdk/util-user-agent-browser": 3.511.0 - "@aws-sdk/util-user-agent-node": 3.511.0 + "@aws-sdk/middleware-host-header": 3.515.0 + "@aws-sdk/middleware-logger": 3.515.0 + "@aws-sdk/middleware-recursion-detection": 3.515.0 + "@aws-sdk/middleware-user-agent": 3.515.0 + "@aws-sdk/region-config-resolver": 3.515.0 + "@aws-sdk/types": 3.515.0 + "@aws-sdk/util-endpoints": 3.515.0 + "@aws-sdk/util-user-agent-browser": 3.515.0 + "@aws-sdk/util-user-agent-node": 3.515.0 "@smithy/config-resolver": ^2.1.1 "@smithy/core": ^1.3.2 "@smithy/fetch-http-handler": ^2.4.1 @@ -669,27 +669,27 @@ __metadata: "@smithy/util-utf8": ^2.1.1 tslib: ^2.5.0 peerDependencies: - "@aws-sdk/credential-provider-node": ^3.513.0 - checksum: 655dbe99fde0d9413eb0c8f2c91815931ecc27eb00d470773acf968b3ceebb007bb8cffebe1261a6dc7af1ebf0a8a2d5d00060d02bf3e3be09f97bf71a4ce284 + "@aws-sdk/credential-provider-node": ^3.515.0 + checksum: f220a9ba8542460b2aa91ad060302fb9e68bdf096ecca2ec1d6e525f4df1036b330cb85d20bac3e8399276c0d8d8d388b3f2191b58804919c68369afac0be37b languageName: node linkType: hard -"@aws-sdk/client-sso@npm:3.513.0": - version: 3.513.0 - resolution: "@aws-sdk/client-sso@npm:3.513.0" +"@aws-sdk/client-sso@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/client-sso@npm:3.515.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 "@aws-sdk/core": 3.513.0 - "@aws-sdk/middleware-host-header": 3.511.0 - "@aws-sdk/middleware-logger": 3.511.0 - "@aws-sdk/middleware-recursion-detection": 3.511.0 - "@aws-sdk/middleware-user-agent": 3.511.0 - "@aws-sdk/region-config-resolver": 3.511.0 - "@aws-sdk/types": 3.511.0 - "@aws-sdk/util-endpoints": 3.511.0 - "@aws-sdk/util-user-agent-browser": 3.511.0 - "@aws-sdk/util-user-agent-node": 3.511.0 + "@aws-sdk/middleware-host-header": 3.515.0 + "@aws-sdk/middleware-logger": 3.515.0 + "@aws-sdk/middleware-recursion-detection": 3.515.0 + "@aws-sdk/middleware-user-agent": 3.515.0 + "@aws-sdk/region-config-resolver": 3.515.0 + "@aws-sdk/types": 3.515.0 + "@aws-sdk/util-endpoints": 3.515.0 + "@aws-sdk/util-user-agent-browser": 3.515.0 + "@aws-sdk/util-user-agent-node": 3.515.0 "@smithy/config-resolver": ^2.1.1 "@smithy/core": ^1.3.2 "@smithy/fetch-http-handler": ^2.4.1 @@ -716,26 +716,26 @@ __metadata: "@smithy/util-retry": ^2.1.1 "@smithy/util-utf8": ^2.1.1 tslib: ^2.5.0 - checksum: 1c5a0465de54cb03e6fe7b1d5543638184227c2019a0eeb4537a42b6da0a9ef698abca25bb967b9fcdd3258ac73dfe0c8e120d96d10994ab9131b28533d0fb1f + checksum: 12287dfa469fb2c6b5bedd3cbd37f7416f8234669b5ed0ff38cb1217d746ba6a5e6ff227b091a7751d1c20489a6b8bd93bcbed8f394cb4c51b6bebb9a9f79108 languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.513.0, @aws-sdk/client-sts@npm:^3.350.0": - version: 3.513.0 - resolution: "@aws-sdk/client-sts@npm:3.513.0" +"@aws-sdk/client-sts@npm:3.515.0, @aws-sdk/client-sts@npm:^3.350.0": + version: 3.515.0 + resolution: "@aws-sdk/client-sts@npm:3.515.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 "@aws-sdk/core": 3.513.0 - "@aws-sdk/middleware-host-header": 3.511.0 - "@aws-sdk/middleware-logger": 3.511.0 - "@aws-sdk/middleware-recursion-detection": 3.511.0 - "@aws-sdk/middleware-user-agent": 3.511.0 - "@aws-sdk/region-config-resolver": 3.511.0 - "@aws-sdk/types": 3.511.0 - "@aws-sdk/util-endpoints": 3.511.0 - "@aws-sdk/util-user-agent-browser": 3.511.0 - "@aws-sdk/util-user-agent-node": 3.511.0 + "@aws-sdk/middleware-host-header": 3.515.0 + "@aws-sdk/middleware-logger": 3.515.0 + "@aws-sdk/middleware-recursion-detection": 3.515.0 + "@aws-sdk/middleware-user-agent": 3.515.0 + "@aws-sdk/region-config-resolver": 3.515.0 + "@aws-sdk/types": 3.515.0 + "@aws-sdk/util-endpoints": 3.515.0 + "@aws-sdk/util-user-agent-browser": 3.515.0 + "@aws-sdk/util-user-agent-node": 3.515.0 "@smithy/config-resolver": ^2.1.1 "@smithy/core": ^1.3.2 "@smithy/fetch-http-handler": ^2.4.1 @@ -764,8 +764,8 @@ __metadata: fast-xml-parser: 4.2.5 tslib: ^2.5.0 peerDependencies: - "@aws-sdk/credential-provider-node": ^3.513.0 - checksum: 4e89fd8f4aef57a777aff20e1afd5c502595c03ba1e21ece5940ea1b2d422c41e8bde83071ba42b96a8bfa4520197375e7f5e98a808c24c96673fc95fa4cdb3f + "@aws-sdk/credential-provider-node": ^3.515.0 + checksum: 9af6a2484909e88a83c411551d55ad149c80a8f449c2e54c499769535243602a6283cd71f6a0cf975b295a321a74e90eb95f6659bba93bae3d12e2186e7545f4 languageName: node linkType: hard @@ -783,36 +783,36 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-cognito-identity@npm:3.514.0": - version: 3.514.0 - resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.514.0" +"@aws-sdk/credential-provider-cognito-identity@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.515.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.514.0 - "@aws-sdk/types": 3.511.0 + "@aws-sdk/client-cognito-identity": 3.515.0 + "@aws-sdk/types": 3.515.0 "@smithy/property-provider": ^2.1.1 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: 2a13f19f7f5161f388d6a63fd3b6d5e666ba5b39e40d9a3f935aded9dbec423e0d89f2da8920212e2b1e63dfab690187a45e00bdb3e5c109dc7a2a156de2d066 + checksum: cb8cb5fa19b3e10e0a816eddda0a56a412da6bc68eba4807698ed94ef6bf2f3de288d959ced099b399dfc29f08154c84f8c025816e94226e5fb21c605e710542 languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.511.0" +"@aws-sdk/credential-provider-env@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/property-provider": ^2.1.1 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: c19f98e0a59324cb9cd59220c91ed41ee6ee507de9acdb233f1a280db14491883c24d711d6a496f03d15b9301496ab561dba8d78dfdac5477c43c9d0bb2fcced + checksum: 3573bc3f1aa89bc8eedb9eb39c8c1d501a68aec5eb059364a1091c8bf10dfda9cfbd78ee49d3ad25ec1012f765a4464363c4cd70997e94005fd21245871a4229 languageName: node linkType: hard -"@aws-sdk/credential-provider-http@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.511.0" +"@aws-sdk/credential-provider-http@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/fetch-http-handler": ^2.4.1 "@smithy/node-http-handler": ^2.3.1 "@smithy/property-provider": ^2.1.1 @@ -821,111 +821,111 @@ __metadata: "@smithy/types": ^2.9.1 "@smithy/util-stream": ^2.1.1 tslib: ^2.5.0 - checksum: d6dc32a2e1cab7ff6b603aa087b80ec854064a9f490210d8d50db2b68f4586b7cfc78de71d6ae1e21788e8e171c6ee2c4c1fa6876ce59bab018abfd9cab13b2a + checksum: d13943dc7a83c9c129dd03a8b337b7753c791441d65a894085e00146d807738b420b9127f570a32497665be4f6e1cc8eeefd7cb1b013a04789d874c8b23b829f languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.513.0": - version: 3.513.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.513.0" +"@aws-sdk/credential-provider-ini@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.515.0" dependencies: - "@aws-sdk/client-sts": 3.513.0 - "@aws-sdk/credential-provider-env": 3.511.0 - "@aws-sdk/credential-provider-process": 3.511.0 - "@aws-sdk/credential-provider-sso": 3.513.0 - "@aws-sdk/credential-provider-web-identity": 3.513.0 - "@aws-sdk/types": 3.511.0 + "@aws-sdk/client-sts": 3.515.0 + "@aws-sdk/credential-provider-env": 3.515.0 + "@aws-sdk/credential-provider-process": 3.515.0 + "@aws-sdk/credential-provider-sso": 3.515.0 + "@aws-sdk/credential-provider-web-identity": 3.515.0 + "@aws-sdk/types": 3.515.0 "@smithy/credential-provider-imds": ^2.2.1 "@smithy/property-provider": ^2.1.1 "@smithy/shared-ini-file-loader": ^2.3.1 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: d4e9f0486f44ca7271f8e245b9db483cc32a5b7600dc4de586fcbacf050a3b67c083c1bb9c86408a91ff1c46fd1b6c6428f592ca8d7537293c09f2359946039a + checksum: c136d4257460be8331d7645854b7e3c91205a1eb12efd3dcbcd84501c787085292d1ccc4578c4776308d91748bde5af2c6eaa873b56aed83ab472a878a2d8883 languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.514.0, @aws-sdk/credential-provider-node@npm:^3.350.0": - version: 3.514.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.514.0" +"@aws-sdk/credential-provider-node@npm:3.515.0, @aws-sdk/credential-provider-node@npm:^3.350.0": + version: 3.515.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.515.0" dependencies: - "@aws-sdk/credential-provider-env": 3.511.0 - "@aws-sdk/credential-provider-http": 3.511.0 - "@aws-sdk/credential-provider-ini": 3.513.0 - "@aws-sdk/credential-provider-process": 3.511.0 - "@aws-sdk/credential-provider-sso": 3.513.0 - "@aws-sdk/credential-provider-web-identity": 3.513.0 - "@aws-sdk/types": 3.511.0 + "@aws-sdk/credential-provider-env": 3.515.0 + "@aws-sdk/credential-provider-http": 3.515.0 + "@aws-sdk/credential-provider-ini": 3.515.0 + "@aws-sdk/credential-provider-process": 3.515.0 + "@aws-sdk/credential-provider-sso": 3.515.0 + "@aws-sdk/credential-provider-web-identity": 3.515.0 + "@aws-sdk/types": 3.515.0 "@smithy/credential-provider-imds": ^2.2.1 "@smithy/property-provider": ^2.1.1 "@smithy/shared-ini-file-loader": ^2.3.1 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: ceeded87585fde1093dac1a84ffa0c0d1377f844508431b06877529de40625d2b67ad23269a7ac32e0cac3338a7051a23c51095eb22cea359b80d3ac72a34b81 + checksum: c51f267c61de0d82afe47d97cdf58971e3b8eec6e7364fe28d3867addd65e156358b96c39a335fad521e9a6925b349a967ae3eed1aa6e9cb4bcc1f0931e3ed50 languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.511.0" +"@aws-sdk/credential-provider-process@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/property-provider": ^2.1.1 "@smithy/shared-ini-file-loader": ^2.3.1 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: ec3be8da713542d61c40d38fb83d067115d0e54e9847ebe7291ed17aa67bbae731e9b2e54cf833bdc75b1b171e663bbbb005308e69634dc4a88926887c78881b + checksum: 11159b4c9502218ec6cba9a46ddc120e53aec7f04507c14d4e99a186073cfd363af438c623705890a2e8f6cc792475ebd14c82766dad82dabf7f20d9708f7faf languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.513.0": - version: 3.513.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.513.0" +"@aws-sdk/credential-provider-sso@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.515.0" dependencies: - "@aws-sdk/client-sso": 3.513.0 - "@aws-sdk/token-providers": 3.513.0 - "@aws-sdk/types": 3.511.0 + "@aws-sdk/client-sso": 3.515.0 + "@aws-sdk/token-providers": 3.515.0 + "@aws-sdk/types": 3.515.0 "@smithy/property-provider": ^2.1.1 "@smithy/shared-ini-file-loader": ^2.3.1 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: eafa07c7502136dbed7b4308d921fec87f381fbc2c27c1d4ba8d34d902e3a4ef6b95713a6fa7be2fe82fa68fdf06e5dbcd971b4d55c66c7b2d3c4a36a58fd2cc + checksum: fbe1eebc50e9bd3715bca4e6ee1a2922cf1ea383953730a6bd3b88b12f23a95cb3ff0edaf8578c81156ef65648eb0295f5c39ed6ae2c8e16b6ce9d4c46f207e9 languageName: node linkType: hard -"@aws-sdk/credential-provider-web-identity@npm:3.513.0": - version: 3.513.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.513.0" +"@aws-sdk/credential-provider-web-identity@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.515.0" dependencies: - "@aws-sdk/client-sts": 3.513.0 - "@aws-sdk/types": 3.511.0 + "@aws-sdk/client-sts": 3.515.0 + "@aws-sdk/types": 3.515.0 "@smithy/property-provider": ^2.1.1 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: 2a885d53f6a3b4a3f461095af3be0e4c7f48b93a21619f97e2ac076f43cabcf703e6cb5f57f594d7288b63dc5dec12a2096ae6c93993f82fdfee5f3227307c63 + checksum: f0a7e9855f78849143c3139c613cc1531a88272f3ec039d23ac9366b94495a3e07212ade9541e56c93560ad9f58600376e9de38706a4cd97aaf5f400911361cd languageName: node linkType: hard "@aws-sdk/credential-providers@npm:^3.350.0": - version: 3.514.0 - resolution: "@aws-sdk/credential-providers@npm:3.514.0" + version: 3.515.0 + resolution: "@aws-sdk/credential-providers@npm:3.515.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.514.0 - "@aws-sdk/client-sso": 3.513.0 - "@aws-sdk/client-sts": 3.513.0 - "@aws-sdk/credential-provider-cognito-identity": 3.514.0 - "@aws-sdk/credential-provider-env": 3.511.0 - "@aws-sdk/credential-provider-http": 3.511.0 - "@aws-sdk/credential-provider-ini": 3.513.0 - "@aws-sdk/credential-provider-node": 3.514.0 - "@aws-sdk/credential-provider-process": 3.511.0 - "@aws-sdk/credential-provider-sso": 3.513.0 - "@aws-sdk/credential-provider-web-identity": 3.513.0 - "@aws-sdk/types": 3.511.0 + "@aws-sdk/client-cognito-identity": 3.515.0 + "@aws-sdk/client-sso": 3.515.0 + "@aws-sdk/client-sts": 3.515.0 + "@aws-sdk/credential-provider-cognito-identity": 3.515.0 + "@aws-sdk/credential-provider-env": 3.515.0 + "@aws-sdk/credential-provider-http": 3.515.0 + "@aws-sdk/credential-provider-ini": 3.515.0 + "@aws-sdk/credential-provider-node": 3.515.0 + "@aws-sdk/credential-provider-process": 3.515.0 + "@aws-sdk/credential-provider-sso": 3.515.0 + "@aws-sdk/credential-provider-web-identity": 3.515.0 + "@aws-sdk/types": 3.515.0 "@smithy/credential-provider-imds": ^2.2.1 "@smithy/property-provider": ^2.1.1 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: 87468c93d84406a3cebb1df81311b5fd16ee93331c353991657423da90c960b1e3d4d033274efb81090c814dfff83064eec693abd4e6fba878961832b033b8d7 + checksum: 8890e83fc19072c51cee8d50ee7168800b9775aa00bcb7a0feb836e60fbae0fb8ba55133d256719033cd7ccda0f5881350474ba3f4769016f01ce7de4ef7b6e5 languageName: node linkType: hard @@ -951,8 +951,8 @@ __metadata: linkType: hard "@aws-sdk/lib-storage@npm:^3.350.0": - version: 3.514.0 - resolution: "@aws-sdk/lib-storage@npm:3.514.0" + version: 3.515.0 + resolution: "@aws-sdk/lib-storage@npm:3.515.0" dependencies: "@smithy/abort-controller": ^2.1.1 "@smithy/middleware-endpoint": ^2.4.1 @@ -963,22 +963,22 @@ __metadata: tslib: ^2.5.0 peerDependencies: "@aws-sdk/client-s3": ^3.0.0 - checksum: 1a122a966bd2e7c627a1a69ef6d8c441ca6f439a503d95cc58cca3f0333bc3d2f2c9fd715b4a6abb009a868240c8a1e33607002b7f6abe89e1d5c26fc3823842 + checksum: b4d7b3783508ce3ef93150b2a249490c5af803d02d91ce81aebf0ec055870aae3260d4d66e9bf1d4234fb61d11cfaa54f2916c9c2572cf4cb6ee1b15993c41b5 languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.511.0" +"@aws-sdk/middleware-bucket-endpoint@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@aws-sdk/util-arn-parser": 3.495.0 "@smithy/node-config-provider": ^2.2.1 "@smithy/protocol-http": ^3.1.1 "@smithy/types": ^2.9.1 "@smithy/util-config-provider": ^2.2.1 tslib: ^2.5.0 - checksum: 23272bf6b5a6a7e8ae97bf2ad896487b670a1db766a2704606eb1fd852a273d99fb468bf3f7f3dddc6df7cdf5812a2195f842f949add6bc272fb90ac80241217 + checksum: 8ecec09ac50c33a24178e73be6b4238e5047984eebf54c4786392e82d2b1cdd09807ee97104f603d22890a58657335843f9587c66e544c2ffbb9a25f3e3bf065 languageName: node linkType: hard @@ -995,85 +995,85 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.511.0" +"@aws-sdk/middleware-expect-continue@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/protocol-http": ^3.1.1 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: be66cd2cecff5ba6bb9cc1a3368f2f488b28d415e9122bded2d1810a57014860d63a91ef64c9edab854fe67f339d75a1ee84c6d5f6de9e534ec4ea708871ea90 + checksum: c989e0e55f51c631f914b444a0e3a6a81c79c1ad8046346c16a4ccfbb77aeaf48ba948a6b8185fc36c00abf07951cc374c3673da6d23d7de6cd3ec8d5b4d840e languageName: node linkType: hard -"@aws-sdk/middleware-flexible-checksums@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.511.0" +"@aws-sdk/middleware-flexible-checksums@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.515.0" dependencies: "@aws-crypto/crc32": 3.0.0 "@aws-crypto/crc32c": 3.0.0 - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/is-array-buffer": ^2.1.1 "@smithy/protocol-http": ^3.1.1 "@smithy/types": ^2.9.1 "@smithy/util-utf8": ^2.1.1 tslib: ^2.5.0 - checksum: 5d95e405b5584c5fcc4c88f5ed7f49a85c95263d13a0859e167eda43ba3171233f38280430e42cc40baa923d64f02af36e442e7f374600ac8153ddfd7ba96853 + checksum: 89f2df7a3dd40c174586aec1349e4e144825cffb252df843b115390702523dc6cfb745756a69a1ab1e77e44340fd55bed04be3856fe96d937af5702bcbcf869b languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.511.0" +"@aws-sdk/middleware-host-header@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/protocol-http": ^3.1.1 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: 4cdbe0959d17c32928025e5f57b56ce35e6a94bf907be5ef00e1b564735528a585749b95f0c91d9281275275e9e77a82ad946b1daeb0a320ea767bb602cd0d61 + checksum: ff066cf47b0ba2c64bd70efdec795ac2da8bad7ba8dd44913c98f42b153ca6e753b13b6c1ef7075499590279a5cc49b5a60511dae4512dcdb11a62a0e67fa061 languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.511.0" +"@aws-sdk/middleware-location-constraint@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: 2749c882354da4a37cf800d98f2ad14ba128d974c05875e4e6639d4eed731f36bd437bb622ab1d8c3ffc58af7c7b18035fd08e82044c9e5910765aae5cf0db09 + checksum: c3e7c7b51c276eba7ceef05c18416d2cca976c83ac9db227877090c33f676b50b0c90ceaf5d924cd9894a4c2f44c0a2d06ec93da753ac646fecb68d5facef570 languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/middleware-logger@npm:3.511.0" +"@aws-sdk/middleware-logger@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/middleware-logger@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: bcbd5486d63a7ffe0ea4131cff646be728b2f1d862231c133fdc6f67a3f39aafa9c09c059e2cb2c6720d569a3c0d9926e0acb61ccd505acdc48e3b34e706f60b + checksum: 32d251e77f43593ffdd192a4d0628f33773e29c14a3001a4c6519553e94958edbd0fb8e6954a65d1180b0caa16cafe9fc9b362d1ab663db1d1eac84b15667645 languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.511.0" +"@aws-sdk/middleware-recursion-detection@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/protocol-http": ^3.1.1 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: a9e1d7924115f07986b726c2f2bd1705227bf5660c3ff9fc356866600f2336cc0ecea5cf53cca7c48a9856216363774cecf64fa9bbe954e71cd5605fcb6d57b3 + checksum: 23c4a1e4d7de86196acfcfbc84bea84c8c3211c4831fdc7c975a6388022037bd5baa4e5809dca188631f06726b51fcf85af358f9ef526e255dc494b368d0da0c languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.511.0" +"@aws-sdk/middleware-sdk-s3@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@aws-sdk/util-arn-parser": 3.495.0 "@smithy/node-config-provider": ^2.2.1 "@smithy/protocol-http": ^3.1.1 @@ -1082,21 +1082,21 @@ __metadata: "@smithy/types": ^2.9.1 "@smithy/util-config-provider": ^2.2.1 tslib: ^2.5.0 - checksum: 1e9bad58136131aaaac326fa2d05d192ef762217a85e0bc831801b45ed15089ef763c2b5d57f28d0b2dc87d2aca02d894a3570c6e85dd2677d0a78e663fd4f15 + checksum: cb67334b30eee8fcf52637407cab2787353e463bdf5a99a33966f0e765f6f8fc687c4bba2b63ec7a4374b2ab544be807e1849bd910e6f163ff43d036f026e7e1 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sqs@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.511.0" +"@aws-sdk/middleware-sdk-sqs@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/smithy-client": ^2.3.1 "@smithy/types": ^2.9.1 "@smithy/util-hex-encoding": ^2.1.1 "@smithy/util-utf8": ^2.1.1 tslib: ^2.5.0 - checksum: 2b8593c20a40beafc88c03bd75fcf8cecd00ad68ed42f26e64c61a2006a622085764b29b6d05191ea5417a18d3503c455008482faaa4873e4e5404a0ac71e84d + checksum: 67a7d9ed3e975a3fd83266f18ce2d94e3dc457d7001af7031e732b2d96135678dd3323ecae56ffe214f3dbe23d1df295a0cd0d21df7f6b9c98699e6a9b4704ca languageName: node linkType: hard @@ -1110,42 +1110,42 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-signing@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/middleware-signing@npm:3.511.0" +"@aws-sdk/middleware-signing@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/middleware-signing@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/property-provider": ^2.1.1 "@smithy/protocol-http": ^3.1.1 "@smithy/signature-v4": ^2.1.1 "@smithy/types": ^2.9.1 "@smithy/util-middleware": ^2.1.1 tslib: ^2.5.0 - checksum: 383054601027f89065948aa19ed708f9dcc190651bbb61363c0eb2f705d75e62790d2715c4fca4cf7c7e3288f9c1c9b672556799eafa36629cc26d1d42944300 + checksum: 7ee85c70a81b85e455c4411caad79c7b41a0a0fd9696feead394a31ca360b096c74f7b2b6b5d449fcfa622659305618e24a49d15c45cab3afa54503459a9b24a languageName: node linkType: hard -"@aws-sdk/middleware-ssec@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/middleware-ssec@npm:3.511.0" +"@aws-sdk/middleware-ssec@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/middleware-ssec@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: ab21772d16006e9326bd2238ea8b6013f89b35fd3c243ec9212296fefc68ddc54b91f5cde449c1a1119089a002b4c8e2278597649d69744dc015be2964df3ad7 + checksum: 3a91ebaf128ff63665f9aa69b9b2d475ebb8e519da2e94a142bcea7f9b173be52a0476b814e90e88e0936db3371e3c1c090b4e44018f006e1cfc37d2631a36d8 languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.511.0" +"@aws-sdk/middleware-user-agent@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 - "@aws-sdk/util-endpoints": 3.511.0 + "@aws-sdk/types": 3.515.0 + "@aws-sdk/util-endpoints": 3.515.0 "@smithy/protocol-http": ^3.1.1 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: 4d09ca5497e17a748f4034f5c1374cbdf8701fedbd5b3275042dccd734a4e91d52eed5e493f1526cda965ec784502efb4f25ca55874f7996d1bb442895316ef1 + checksum: fd601cb0367d42e38b71494c773d82bde8970f9aafbdbf18d7cadc25732ecc2b787f0cfef2110755d0cef73d6aa3ce2ca77dc5353854bedaf392a69019b39ac2 languageName: node linkType: hard @@ -1193,31 +1193,31 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/region-config-resolver@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.511.0" +"@aws-sdk/region-config-resolver@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/node-config-provider": ^2.2.1 "@smithy/types": ^2.9.1 "@smithy/util-config-provider": ^2.2.1 "@smithy/util-middleware": ^2.1.1 tslib: ^2.5.0 - checksum: a41e119d85c690e957bc00af7a6b822f2bb4c3522c3762799a40a5e0d081cbed6028607b8528b98705af4b7e5ed1a2cbc9e9d39df415597271fba7b1da7f08f5 + checksum: 0ed7fbd6390baebdf511b30877236fa8be8716e0162e2c9e0138c9b41ebda7d99a6f3d6cf66cb4af24761631c2c29102ecfe7a5f08894e1de3c98ca6a135fa74 languageName: node linkType: hard -"@aws-sdk/signature-v4-multi-region@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.511.0" +"@aws-sdk/signature-v4-multi-region@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.515.0" dependencies: - "@aws-sdk/middleware-sdk-s3": 3.511.0 - "@aws-sdk/types": 3.511.0 + "@aws-sdk/middleware-sdk-s3": 3.515.0 + "@aws-sdk/types": 3.515.0 "@smithy/protocol-http": ^3.1.1 "@smithy/signature-v4": ^2.1.1 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: f1a4d3a81310e2867ac973be8bae1a04654dbd543fb9341cd963a53e378b821e5ae189da072f5ab7c86efd00192d0b8da76f54d9f612c30ad20574485c250b0c + checksum: 1f780409af431b3ac91beee294cf4af74fff9f3dffc21ddd1c8a1782a01916da162ceec27c133a9e86452279bdf0005f9118809820d557a248613cd44f0f7ec3 languageName: node linkType: hard @@ -1237,17 +1237,17 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.513.0": - version: 3.513.0 - resolution: "@aws-sdk/token-providers@npm:3.513.0" +"@aws-sdk/token-providers@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/token-providers@npm:3.515.0" dependencies: - "@aws-sdk/client-sso-oidc": 3.513.0 - "@aws-sdk/types": 3.511.0 + "@aws-sdk/client-sso-oidc": 3.515.0 + "@aws-sdk/types": 3.515.0 "@smithy/property-provider": ^2.1.1 "@smithy/shared-ini-file-loader": ^2.3.1 "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: 6f7765e0778814f2d94b8a2489eefecc1b314813af6462cfc4f5527257ece7c1501360664500d519da0fa48312200f040f5a7560928620ff3882c65f52fabe18 + checksum: ab51c440da9772d0ee58948241b975705c171395cf1bad81a4ffd8f11f34106af54dcba930e360fb19489beedc1106ac14432bd27abdfe4b7536dc2113841027 languageName: node linkType: hard @@ -1261,13 +1261,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.511.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": - version: 3.511.0 - resolution: "@aws-sdk/types@npm:3.511.0" +"@aws-sdk/types@npm:3.515.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": + version: 3.515.0 + resolution: "@aws-sdk/types@npm:3.515.0" dependencies: "@smithy/types": ^2.9.1 tslib: ^2.5.0 - checksum: a2082c64b4aabecde26010a48f8535a90c8d3e666e63f82773f8b07dadd7c1ff05d4639c60ddfb7d3533fe4ac55259e34a23995ca868c13e6d7718a1392a6eb8 + checksum: 0874f1814b58eae6e7115c3d08c2bc56e558e73d1ff8c5f833a73b4a0f76a42743c83c36a4b2759177e41b1feff065e85450f7bc235a087b94e67db12f87d298 languageName: node linkType: hard @@ -1301,15 +1301,15 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/util-endpoints@npm:3.511.0" +"@aws-sdk/util-endpoints@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/util-endpoints@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/types": ^2.9.1 "@smithy/util-endpoints": ^1.1.1 tslib: ^2.5.0 - checksum: dfd8fa98e6abeb96edc1239d1c49aef740bc781eb772a05deeb3385d576921121e3a5050f5372cce2bd422848ece728271aadb8887dce413100a289311873b3b + checksum: 1ab8fcd3054dc0366f10813a01130d05f4ba33f1488c1a168f44881cb24f3fbc2393111b7b0fd4dc06c852e4c9a5bbe8a82717b72229b0977cdba8a631ddeee1 languageName: node linkType: hard @@ -1361,23 +1361,23 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-browser@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.511.0" +"@aws-sdk/util-user-agent-browser@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/types": ^2.9.1 bowser: ^2.11.0 tslib: ^2.5.0 - checksum: 714e5bc1faab9aee8c4a2ba02faa9c3d61621d2cc789fad460b613916adf12992c0ab7144368fdfecac10f3ec2b67f5d6da01465e827fe682e2024274c2b5721 + checksum: 40f518006cb7e76d06d83dcf05222b0b0ff47c10b63149cd5db2c0c1db79c8eff34bd582e89c748897bc11697b7b357bdca77d569f57ad0b2081c088752d601f languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:3.511.0": - version: 3.511.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.511.0" +"@aws-sdk/util-user-agent-node@npm:3.515.0": + version: 3.515.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.515.0" dependencies: - "@aws-sdk/types": 3.511.0 + "@aws-sdk/types": 3.515.0 "@smithy/node-config-provider": ^2.2.1 "@smithy/types": ^2.9.1 tslib: ^2.5.0 @@ -1386,7 +1386,7 @@ __metadata: peerDependenciesMeta: aws-crt: optional: true - checksum: 611a71d736d82c74f3585b0dfdd77c329047bd2815fb1782188df433015525e01247ed85ffca60d5a7c618081fd7cb935814d6854a6120071b44261b12a3e740 + checksum: 4e91d9cd5bbe4aa8321417ea1bd9caf3229416ee624b7f67b5206b284a539116692412ca41d60dcb5759b841fed7d9fb570915566d1f7e620578657f89548a23 languageName: node linkType: hard @@ -45069,7 +45069,7 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^9.0.0": +"uuid@npm:^9.0.0, uuid@npm:^9.0.1": version: 9.0.1 resolution: "uuid@npm:9.0.1" bin: From b64ce5a485bbdfd48f0d130a0b3afbc41b6a0e9d Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Thu, 15 Feb 2024 18:50:07 -0600 Subject: [PATCH 19/82] Updated to use default import Signed-off-by: Andre Wanlin --- .changeset/famous-zoos-remain.md | 12 ++++++++++++ plugins/adr-backend/README.md | 4 +--- plugins/airbrake/README.md | 7 +++++-- plugins/azure-devops-backend/README.md | 3 +-- plugins/badges-backend/README.md | 4 ++-- plugins/devtools-backend/README.md | 3 +-- plugins/entity-feedback-backend/README.md | 10 ++++++---- plugins/lighthouse-backend/README.md | 7 +++++-- plugins/linguist-backend/README.md | 3 +-- 9 files changed, 34 insertions(+), 19 deletions(-) create mode 100644 .changeset/famous-zoos-remain.md diff --git a/.changeset/famous-zoos-remain.md b/.changeset/famous-zoos-remain.md new file mode 100644 index 0000000000..be4147c21e --- /dev/null +++ b/.changeset/famous-zoos-remain.md @@ -0,0 +1,12 @@ +--- +'@backstage/plugin-entity-feedback-backend': patch +'@backstage/plugin-azure-devops-backend': patch +'@backstage/plugin-lighthouse-backend': patch +'@backstage/plugin-devtools-backend': patch +'@backstage/plugin-linguist-backend': patch +'@backstage/plugin-badges-backend': patch +'@backstage/plugin-adr-backend': patch +'@backstage/plugin-airbrake': patch +--- + +Updated New Backend System instructions to use default import diff --git a/plugins/adr-backend/README.md b/plugins/adr-backend/README.md index ebf99b4ee1..73af5137ba 100644 --- a/plugins/adr-backend/README.md +++ b/plugins/adr-backend/README.md @@ -65,11 +65,9 @@ The ADR backend plugin has support for the [new backend system](https://backstag In your `packages/backend/src/index.ts` make the following changes: ```diff - -+ import { adrPlugin } from '@backstage/plugin-adr-backend'; const backend = createBackend(); -+ backend.add(adrPlugin()); ++ backend.add(import('@backstage/plugin-adr-backend')); // ... other feature additions diff --git a/plugins/airbrake/README.md b/plugins/airbrake/README.md index 603311f92c..2426a6eb8a 100644 --- a/plugins/airbrake/README.md +++ b/plugins/airbrake/README.md @@ -124,10 +124,13 @@ In your `packages/backend/src/index.ts` make the following changes: ```diff import { createBackend } from '@backstage/backend-defaults'; -+ import { airbrakePlugin } from '@backstage/plugin-airbrake-backend'; + const backend = createBackend(); + // ... other feature additions -+ backend.add(airbrakePlugin()); + ++ backend.add(import('@backstage/plugin-airbrake-backend')); + backend.start(); ``` diff --git a/plugins/azure-devops-backend/README.md b/plugins/azure-devops-backend/README.md index f69951f70d..7c722dbe26 100644 --- a/plugins/azure-devops-backend/README.md +++ b/plugins/azure-devops-backend/README.md @@ -84,13 +84,12 @@ In your `packages/backend/src/index.ts` make the following changes: ```diff import { createBackend } from '@backstage/backend-defaults'; -+ import { azureDevOpsPlugin } from '@backstage/plugin-azure-devops-backend'; const backend = createBackend(); // ... other feature additions -+ backend.add(azureDevOpsPlugin()); ++ backend.add(import('@backstage/plugin-azure-devops-backend')); backend.start(); ``` diff --git a/plugins/badges-backend/README.md b/plugins/badges-backend/README.md index 1737482080..4e35b30c13 100644 --- a/plugins/badges-backend/README.md +++ b/plugins/badges-backend/README.md @@ -84,12 +84,12 @@ In your `packages/backend/src/index.ts` make the following changes: ```diff import { createBackend } from '@backstage/backend-defaults'; -+ import { badgesPlugin } from '@backstage/plugin-badges-backend'; + const backend = createBackend(); // ... other feature additions -+ backend.add(badgesPlugin()); ++ backend.add(import('@backstage/plugin-badges-backend')); backend.start(); ``` diff --git a/plugins/devtools-backend/README.md b/plugins/devtools-backend/README.md index c9226a92ab..4439c8cd9f 100644 --- a/plugins/devtools-backend/README.md +++ b/plugins/devtools-backend/README.md @@ -57,13 +57,12 @@ In your `packages/backend/src/index.ts` make the following changes: ```diff import { createBackend } from '@backstage/backend-defaults'; -+ import { devtoolsPlugin } from '@backstage/plugin-devtools-backend'; const backend = createBackend(); // ... other feature additions -+ backend.add(devtoolsPlugin()); ++ backend.add(import('@backstage/plugin-devtools-backend')); backend.start(); ``` diff --git a/plugins/entity-feedback-backend/README.md b/plugins/entity-feedback-backend/README.md index a3aae695e2..cef580a580 100644 --- a/plugins/entity-feedback-backend/README.md +++ b/plugins/entity-feedback-backend/README.md @@ -59,11 +59,13 @@ The Entity Feedback backend plugin has support for the [new backend system](http In your `packages/backend/src/index.ts` make the following changes: ```diff -+ import { entityFeedbackPlugin } from '@backstage/plugin-entity-feedback-backend'; + import { createBackend } from '@backstage/backend-defaults'; -const backend = createBackend(); -+ backend.add(entityFeedbackPlugin()); -// ... other feature additions + const backend = createBackend(); + + // ... other feature additions + ++ backend.add(import(@backstage/plugin-entity-feedback-backend)); backend.start(); ``` diff --git a/plugins/lighthouse-backend/README.md b/plugins/lighthouse-backend/README.md index 06455d90b4..df6c2415d9 100644 --- a/plugins/lighthouse-backend/README.md +++ b/plugins/lighthouse-backend/README.md @@ -72,10 +72,13 @@ In your `packages/backend/src/index.ts` make the following changes: ```diff import { createBackend } from '@backstage/backend-defaults'; -+ import { lighthousePlugin } from '@backstage/plugin-lighthouse-backend'; + const backend = createBackend(); + // ... other feature additions -+ backend.add(lighthousePlugin()); + ++ backend.add(import('@backstage/plugin-lighthouse-backend')); + backend.start(); ``` diff --git a/plugins/linguist-backend/README.md b/plugins/linguist-backend/README.md index 3bc441c238..8939bbe303 100644 --- a/plugins/linguist-backend/README.md +++ b/plugins/linguist-backend/README.md @@ -64,13 +64,12 @@ In your `packages/backend/src/index.ts` make the following changes: ```diff import { createBackend } from '@backstage/backend-defaults'; -+ import { linguistPlugin } from '@backstage/plugin-linguist-backend'; const backend = createBackend(); // ... other feature additions -+ backend.add(linguistPlugin()); ++ backend.add(import('@backstage/plugin-linguist-backend')); backend.start(); ``` From f3a63d07d6c67fccb9c5390f86acc87e71ca87f4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 01:15:49 +0000 Subject: [PATCH 20/82] chore(deps): update dependency swr to v2.2.5 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c14cb29002..cb68ad962b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -43294,14 +43294,14 @@ __metadata: linkType: hard "swr@npm:^2.0.0": - version: 2.2.4 - resolution: "swr@npm:2.2.4" + version: 2.2.5 + resolution: "swr@npm:2.2.5" dependencies: client-only: ^0.0.1 use-sync-external-store: ^1.2.0 peerDependencies: react: ^16.11.0 || ^17.0.0 || ^18.0.0 - checksum: d1398f89fd68af0e0cb6100a5769b1e17c0dbe8a778898643ad28456acda64add43344754c7d919e3f2ca82854adf86ff7d465aba25a2d555bcb669e457138f8 + checksum: c6e6a5bd254951b22e5fd0930a95c7f79b5d0657f803c41ba1542cd6376623fb70b1895049d54ddde26da63b91951ae9d62a06772f82be28c1014d421e5b7aa9 languageName: node linkType: hard From 9873c44c2493d70a3d970adad0d904fdf0959196 Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Thu, 15 Feb 2024 14:39:44 +0200 Subject: [PATCH 21/82] feat: define signal type for notifications Signed-off-by: Heikki Hellgren --- .changeset/honest-pets-judge.md | 7 ++ .../src/service/router.ts | 69 +++++++++---------- plugins/notifications-common/api-report.md | 15 ++++ plugins/notifications-common/src/types.ts | 15 ++++ plugins/notifications/api-report.md | 5 ++ .../notifications/src/api/NotificationsApi.ts | 2 + .../src/api/NotificationsClient.test.ts | 14 ++++ .../src/api/NotificationsClient.ts | 4 ++ .../NotificationsSideBarItem.tsx | 53 +++++++------- .../src/hooks/useWebNotifications.ts | 11 ++- 10 files changed, 130 insertions(+), 65 deletions(-) create mode 100644 .changeset/honest-pets-judge.md diff --git a/.changeset/honest-pets-judge.md b/.changeset/honest-pets-judge.md new file mode 100644 index 0000000000..468fc1b6d5 --- /dev/null +++ b/.changeset/honest-pets-judge.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-notifications-backend': patch +'@backstage/plugin-notifications-common': patch +'@backstage/plugin-notifications': patch +--- + +Add support for signal type in notifications diff --git a/plugins/notifications-backend/src/service/router.ts b/plugins/notifications-backend/src/service/router.ts index b293ea4a1f..6c745e158e 100644 --- a/plugins/notifications-backend/src/service/router.ts +++ b/plugins/notifications-backend/src/service/router.ts @@ -42,7 +42,9 @@ import { AuthenticationError, InputError } from '@backstage/errors'; import { DiscoveryService, LoggerService } from '@backstage/backend-plugin-api'; import { SignalService } from '@backstage/plugin-signals-node'; import { + NewNotificationSignal, Notification, + NotificationReadSignal, NotificationType, } from '@backstage/plugin-notifications-common'; @@ -206,6 +208,21 @@ export async function createRouter( res.send(notifications); }); + router.get('/:id', async (req, res) => { + const user = await getUser(req); + const opts: NotificationGetOptions = { + user: user, + limit: 1, + ids: [req.params.id], + }; + const notifications = await store.getNotifications(opts); + if (notifications.length !== 1) { + res.status(404).send({ error: 'Not found' }); + return; + } + res.send(notifications[0]); + }); + router.get('/status', async (req, res) => { const user = await getUser(req); const status = await store.getStatus({ user, type: 'undone' }); @@ -214,38 +231,18 @@ export async function createRouter( router.post('/update', async (req, res) => { const user = await getUser(req); - const { ids, done, read, saved } = req.body; + const { ids, read, saved } = req.body; if (!ids || !Array.isArray(ids)) { throw new InputError(); } - if (done === true) { - await store.markDone({ user, ids }); - if (signalService) { - await signalService.publish({ - recipients: [user], - message: { action: 'done', notification_ids: ids }, - channel: 'notifications', - }); - } - } else if (done === false) { - await store.markUndone({ user, ids }); - if (signalService) { - await signalService.publish({ - recipients: [user], - message: { action: 'undone', notification_ids: ids }, - channel: 'notifications', - }); - } - } - if (read === true) { await store.markRead({ user, ids }); if (signalService) { - await signalService.publish({ + await signalService.publish({ recipients: [user], - message: { action: 'mark_read', notification_ids: ids }, + message: { action: 'notification_read', notification_ids: ids }, channel: 'notifications', }); } @@ -253,9 +250,9 @@ export async function createRouter( await store.markUnread({ user: user, ids }); if (signalService) { - await signalService.publish({ + await signalService.publish({ recipients: [user], - message: { action: 'mark_unread', notification_ids: ids }, + message: { action: 'notification_unread', notification_ids: ids }, channel: 'notifications', }); } @@ -285,7 +282,7 @@ export async function createRouter( throw new AuthenticationError(); } - const { title, link, description, scope } = payload; + const { title, link, scope } = payload; if (!recipients || !title || !origin || !link) { logger.error(`Invalid notification request received`); @@ -344,17 +341,17 @@ export async function createRouter( processorSendNotification(ret); notifications.push(ret); - } - if (signalService) { - await signalService.publish({ - recipients: entityRef === null ? null : uniqueUsers, - message: { - action: 'new_notification', - notification: { title, description, link }, - }, - channel: 'notifications', - }); + if (signalService) { + await signalService.publish({ + recipients: user, + message: { + action: 'new_notification', + notification_id: ret.id, + }, + channel: 'notifications', + }); + } } res.json(notifications); diff --git a/plugins/notifications-common/api-report.md b/plugins/notifications-common/api-report.md index d2dc1afb9d..6f40c76e58 100644 --- a/plugins/notifications-common/api-report.md +++ b/plugins/notifications-common/api-report.md @@ -3,6 +3,12 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +// @public (undocumented) +export type NewNotificationSignal = { + action: 'new_notification'; + notification_id: string; +}; + // @public (undocumented) type Notification_2 = { id: string; @@ -28,9 +34,18 @@ export type NotificationPayload = { icon?: string; }; +// @public (undocumented) +export type NotificationReadSignal = { + action: 'notification_read' | 'notification_unread'; + notification_ids: string[]; +}; + // @public (undocumented) export type NotificationSeverity = 'critical' | 'high' | 'normal' | 'low'; +// @public (undocumented) +export type NotificationSignal = NewNotificationSignal | NotificationReadSignal; + // @public (undocumented) export type NotificationStatus = { unread: number; diff --git a/plugins/notifications-common/src/types.ts b/plugins/notifications-common/src/types.ts index 1e7469244f..4d71004265 100644 --- a/plugins/notifications-common/src/types.ts +++ b/plugins/notifications-common/src/types.ts @@ -51,3 +51,18 @@ export type NotificationStatus = { unread: number; read: number; }; + +/** @public */ +export type NewNotificationSignal = { + action: 'new_notification'; + notification_id: string; +}; + +/** @public */ +export type NotificationReadSignal = { + action: 'notification_read' | 'notification_unread'; + notification_ids: string[]; +}; + +/** @public */ +export type NotificationSignal = NewNotificationSignal | NotificationReadSignal; diff --git a/plugins/notifications/api-report.md b/plugins/notifications/api-report.md index e2071dad14..0f5d7a0049 100644 --- a/plugins/notifications/api-report.md +++ b/plugins/notifications/api-report.md @@ -26,6 +26,8 @@ export type GetNotificationsOptions = { // @public (undocumented) export interface NotificationsApi { + // (undocumented) + getNotification(id: string): Promise; // (undocumented) getNotifications( options?: GetNotificationsOptions, @@ -45,6 +47,8 @@ export const notificationsApiRef: ApiRef; export class NotificationsClient implements NotificationsApi { constructor(options: { discoveryApi: DiscoveryApi; fetchApi: FetchApi }); // (undocumented) + getNotification(id: string): Promise; + // (undocumented) getNotifications( options?: GetNotificationsOptions, ): Promise; @@ -128,6 +132,7 @@ export function useWebNotifications(): { sendWebNotification: (options: { title: string; description: string; + link?: string; }) => Notification | null; }; diff --git a/plugins/notifications/src/api/NotificationsApi.ts b/plugins/notifications/src/api/NotificationsApi.ts index 775dc6b244..266c8a1ee5 100644 --- a/plugins/notifications/src/api/NotificationsApi.ts +++ b/plugins/notifications/src/api/NotificationsApi.ts @@ -45,6 +45,8 @@ export type UpdateNotificationsOptions = { export interface NotificationsApi { getNotifications(options?: GetNotificationsOptions): Promise; + getNotification(id: string): Promise; + getStatus(): Promise; updateNotifications( diff --git a/plugins/notifications/src/api/NotificationsClient.test.ts b/plugins/notifications/src/api/NotificationsClient.test.ts index a7a2d1e5a7..1312b99cf4 100644 --- a/plugins/notifications/src/api/NotificationsClient.test.ts +++ b/plugins/notifications/src/api/NotificationsClient.test.ts @@ -74,6 +74,20 @@ describe('NotificationsClient', () => { expect(response).toEqual(expectedResp); }); + it('should fetch single notification', async () => { + server.use( + rest.get(`${mockBaseUrl}/:id`, (req, res, ctx) => { + expect(req.params.id).toBe('acdaa8ca-262b-43c1-b74b-de06e5f3b3c7'); + return res(ctx.json(testNotification)); + }), + ); + + const response = await client.getNotification( + 'acdaa8ca-262b-43c1-b74b-de06e5f3b3c7', + ); + expect(response).toEqual(testNotification); + }); + it('should fetch status from correct endpoint', async () => { server.use( rest.get(`${mockBaseUrl}/status`, (_, res, ctx) => diff --git a/plugins/notifications/src/api/NotificationsClient.ts b/plugins/notifications/src/api/NotificationsClient.ts index fe7a90d3e8..9ef7b287ab 100644 --- a/plugins/notifications/src/api/NotificationsClient.ts +++ b/plugins/notifications/src/api/NotificationsClient.ts @@ -60,6 +60,10 @@ export class NotificationsClient implements NotificationsApi { return await this.request(urlSegment); } + async getNotification(id: string): Promise { + return await this.request(`${id}`); + } + async getStatus(): Promise { return await this.request('status'); } diff --git a/plugins/notifications/src/components/NotificationsSideBarItem/NotificationsSideBarItem.tsx b/plugins/notifications/src/components/NotificationsSideBarItem/NotificationsSideBarItem.tsx index 90fba009a3..2163c6660f 100644 --- a/plugins/notifications/src/components/NotificationsSideBarItem/NotificationsSideBarItem.tsx +++ b/plugins/notifications/src/components/NotificationsSideBarItem/NotificationsSideBarItem.tsx @@ -17,12 +17,13 @@ import React, { useEffect } from 'react'; import { useNotificationsApi } from '../../hooks'; import { SidebarItem } from '@backstage/core-components'; import NotificationsIcon from '@material-ui/icons/Notifications'; -import { useRouteRef } from '@backstage/core-plugin-api'; +import { useApi, useRouteRef } from '@backstage/core-plugin-api'; import { rootRouteRef } from '../../routes'; import { useSignal } from '@backstage/plugin-signals-react'; +import { NotificationSignal } from '@backstage/plugin-notifications-common'; import { useWebNotifications } from '../../hooks/useWebNotifications'; import { useTitleCounter } from '../../hooks/useTitleCounter'; -import { JsonObject } from '@backstage/types'; +import { notificationsApiRef } from '../../api'; /** @public */ export const NotificationsSidebarItem = (props?: { @@ -35,11 +36,11 @@ export const NotificationsSidebarItem = (props?: { const { loading, error, value, retry } = useNotificationsApi(api => api.getStatus(), ); + const notificationsApi = useApi(notificationsApiRef); const [unreadCount, setUnreadCount] = React.useState(0); const notificationsRoute = useRouteRef(rootRouteRef); - // TODO: Add signal type support to `useSignal` to make it a bit easier to use // TODO: Do we want to add long polling in case signals are not available - const { lastSignal } = useSignal('notifications'); + const { lastSignal } = useSignal('notifications'); const { sendWebNotification } = useWebNotifications(); const [refresh, setRefresh] = React.useState(false); const { setNotificationCount } = useTitleCounter(); @@ -52,39 +53,35 @@ export const NotificationsSidebarItem = (props?: { }, [refresh, retry]); useEffect(() => { - const handleWebNotification = (signal: JsonObject) => { - if (!webNotificationsEnabled || !('notification' in signal)) { + const handleWebNotification = (signal: NotificationSignal) => { + if (!webNotificationsEnabled || signal.action !== 'new_notification') { return; } - const notificationData = signal.notification as JsonObject; - - if ( - !notificationData || - !('title' in notificationData) || - !('description' in notificationData) || - !('title' in notificationData) - ) { - return; - } - const notification = sendWebNotification({ - title: notificationData.title as string, - description: notificationData.description as string, - }); - if (notification) { - notification.onclick = event => { - event.preventDefault(); - notification.close(); - window.open(notificationData.link as string, '_blank'); - }; - } + notificationsApi + .getNotification(signal.notification_id) + .then(notification => { + if (!notification) { + return; + } + sendWebNotification({ + title: notification.payload.title, + description: notification.payload.description ?? '', + link: notification.payload.link, + }); + }); }; if (lastSignal && lastSignal.action) { handleWebNotification(lastSignal); setRefresh(true); } - }, [lastSignal, sendWebNotification, webNotificationsEnabled]); + }, [ + lastSignal, + sendWebNotification, + webNotificationsEnabled, + notificationsApi, + ]); useEffect(() => { if (!loading && !error && value) { diff --git a/plugins/notifications/src/hooks/useWebNotifications.ts b/plugins/notifications/src/hooks/useWebNotifications.ts index 7e34172a97..bf3b5269f5 100644 --- a/plugins/notifications/src/hooks/useWebNotifications.ts +++ b/plugins/notifications/src/hooks/useWebNotifications.ts @@ -37,7 +37,7 @@ export function useWebNotifications() { }); const sendWebNotification = useCallback( - (options: { title: string; description: string }) => { + (options: { title: string; description: string; link?: string }) => { if (webNotificationPermission !== 'granted') { return null; } @@ -45,6 +45,15 @@ export function useWebNotifications() { const notification = new Notification(options.title, { body: options.description, }); + + notification.onclick = event => { + event.preventDefault(); + notification.close(); + if (options.link) { + window.open(options.link, '_blank'); + } + }; + return notification; }, [webNotificationPermission], From 59fecda9aa4af6b0611b3cefb3743ed0fe3a1efd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 09:20:46 +0000 Subject: [PATCH 22/82] fix(deps): update dependency sass to v1.71.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- microsite/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 14292c36bf..6b522f9cf8 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -10392,15 +10392,15 @@ __metadata: linkType: hard "sass@npm:^1.57.1": - version: 1.70.0 - resolution: "sass@npm:1.70.0" + version: 1.71.0 + resolution: "sass@npm:1.71.0" dependencies: chokidar: ">=3.0.0 <4.0.0" immutable: ^4.0.0 source-map-js: ">=0.6.2 <2.0.0" bin: sass: sass.js - checksum: fd1b622cf9b7fa699a03ec634611997552ece45eb98ac365fef22f42bdcb8ed63b326b64173379c966830c8551ae801e44e4a00d2de16fdadda2dc8f35400bbb + checksum: 5ba6b4b994c7ae94286919d8be8a3692038c27175b4ad3a3ac43f51a91188590d3ddd3a0ef1022135503b9d70d0732efdbedfd56f3ee1a4651549f5b13f8942f languageName: node linkType: hard From ec160939f7a8ea6ec9a912109555a987bb2dc318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 16 Feb 2024 11:07:31 +0100 Subject: [PATCH 23/82] add cmd limiter to the cli MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/nasty-suns-speak.md | 5 +++ packages/repo-tools/src/commands/util.ts | 54 +++++++++++++++--------- 2 files changed, 38 insertions(+), 21 deletions(-) create mode 100644 .changeset/nasty-suns-speak.md diff --git a/.changeset/nasty-suns-speak.md b/.changeset/nasty-suns-speak.md new file mode 100644 index 0000000000..2c5fff25a1 --- /dev/null +++ b/.changeset/nasty-suns-speak.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': patch +--- + +Add an internal limiter on concurrency when launching processes diff --git a/packages/repo-tools/src/commands/util.ts b/packages/repo-tools/src/commands/util.ts index 933945bc5c..e28aae6267 100644 --- a/packages/repo-tools/src/commands/util.ts +++ b/packages/repo-tools/src/commands/util.ts @@ -13,29 +13,41 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { execFile } from 'child_process'; +import os from 'os'; +import pLimit from 'p-limit'; + +// Some commands launch full node processes doing heavy work, which at high +// concurrency levels risk exhausting system resources. Placing the limiter here +// at the root level ensures that the concurrency boundary applies globally, not +// just per-runner. +const limiter = pLimit(os.cpus().length); export function createBinRunner(cwd: string, path: string) { return async (...command: string[]) => - new Promise((resolve, reject) => { - execFile( - 'node', - [path, ...command], - { - cwd, - shell: true, - timeout: 60000, - maxBuffer: 1024 * 1024, - }, - (err, stdout, stderr) => { - if (err) { - reject(new Error(`${err.message}\n${stderr}`)); - } else if (stderr) { - reject(new Error(`Command printed error output: ${stderr}`)); - } else { - resolve(stdout); - } - }, - ); - }); + limiter( + () => + new Promise((resolve, reject) => { + execFile( + 'node', + [path, ...command], + { + cwd, + shell: true, + timeout: 60000, + maxBuffer: 1024 * 1024, + }, + (err, stdout, stderr) => { + if (err) { + reject(new Error(`${err.message}\n${stderr}`)); + } else if (stderr) { + reject(new Error(`Command printed error output: ${stderr}`)); + } else { + resolve(stdout); + } + }, + ); + }), + ); } From 7cac636c9235226d80b143001140171b123bb08f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 10:11:37 +0000 Subject: [PATCH 24/82] fix(deps): update dependency swagger-ui-react to v5.11.7 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4b092ff735..214e70fc91 100644 --- a/yarn.lock +++ b/yarn.lock @@ -43237,8 +43237,8 @@ __metadata: linkType: hard "swagger-ui-react@npm:^5.0.0": - version: 5.11.6 - resolution: "swagger-ui-react@npm:5.11.6" + version: 5.11.7 + resolution: "swagger-ui-react@npm:5.11.7" dependencies: "@babel/runtime-corejs3": ^7.23.9 "@braintree/sanitize-url": =7.0.0 @@ -43277,7 +43277,7 @@ __metadata: peerDependencies: react: ">=16.8.0 <19" react-dom: ">=16.8.0 <19" - checksum: 4556acd2fca69d5b0f7fd1592467818428611f7fce37aeea002c71604c3fdf5314425a99180f08ad257676eec80123cd9ac31e2576102ac9f9fb5f420cb5bbf4 + checksum: b4589abe7d4cdc97fd05f8f8f8b40daee33bb4604faa1f9c513b3ef4765fc407fef37c704dbc56c5493fa5430472e8cb30921a4d4ba544372266d06ef4d1b1e6 languageName: node linkType: hard From 211ec252125b3e7f19f7d20d110f2881e932594d Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 14 Dec 2023 19:03:53 +0100 Subject: [PATCH 25/82] New plugin to publish a git repository on gitea Signed-off-by: cmoulliard --- .../new/factories/scaffolderModule.test.ts | 4 +- .../.eslintrc.js | 1 + .../CHANGELOG.md | 7 + .../scaffolder-backend-module-gitea/README.md | 5 + .../api-report.md | 20 ++ .../catalog-info.yaml | 9 + .../package.json | 41 ++++ .../src/actions/gitea.examples.ts | 158 ++++++++++++ .../src/actions/gitea.test.ts | 49 ++++ .../src/actions/gitea.ts | 232 ++++++++++++++++++ .../src/actions/index.ts | 16 ++ .../src/index.ts | 23 ++ yarn.lock | 16 ++ 13 files changed, 579 insertions(+), 2 deletions(-) create mode 100644 plugins/scaffolder-backend-module-gitea/.eslintrc.js create mode 100644 plugins/scaffolder-backend-module-gitea/CHANGELOG.md create mode 100644 plugins/scaffolder-backend-module-gitea/README.md create mode 100644 plugins/scaffolder-backend-module-gitea/api-report.md create mode 100644 plugins/scaffolder-backend-module-gitea/catalog-info.yaml create mode 100644 plugins/scaffolder-backend-module-gitea/package.json create mode 100644 plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.ts create mode 100644 plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts create mode 100644 plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts create mode 100644 plugins/scaffolder-backend-module-gitea/src/actions/index.ts create mode 100644 plugins/scaffolder-backend-module-gitea/src/index.ts diff --git a/packages/cli/src/lib/new/factories/scaffolderModule.test.ts b/packages/cli/src/lib/new/factories/scaffolderModule.test.ts index b43946228b..767ae0fc44 100644 --- a/packages/cli/src/lib/new/factories/scaffolderModule.test.ts +++ b/packages/cli/src/lib/new/factories/scaffolderModule.test.ts @@ -77,8 +77,8 @@ describe('scaffolderModule factory', () => { 'templating package.json.hbs', 'templating index.ts.hbs', 'copying index.ts', - 'copying example.test.ts', - 'copying example.ts', + 'copying gitea.test.ts', + 'copying gitea.ts', 'copying index.ts', 'Installing:', `moving plugins${sep}scaffolder-backend-module-test`, diff --git a/plugins/scaffolder-backend-module-gitea/.eslintrc.js b/plugins/scaffolder-backend-module-gitea/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/scaffolder-backend-module-gitea/CHANGELOG.md b/plugins/scaffolder-backend-module-gitea/CHANGELOG.md new file mode 100644 index 0000000000..a4f1f20179 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/CHANGELOG.md @@ -0,0 +1,7 @@ +# @backstage/plugin-scaffolder-backend-module-gitea + +## 0.1.0-next.0 + +### Minor Changes + +- TODO: Add Gitea Scaffolder Plugin diff --git a/plugins/scaffolder-backend-module-gitea/README.md b/plugins/scaffolder-backend-module-gitea/README.md new file mode 100644 index 0000000000..84b8ab6ea5 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/README.md @@ -0,0 +1,5 @@ +# backstage-plugin-scaffolder-backend-module-gitea + +The gitea module for [@backstage/plugin-scaffolder-backend](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend). + +_This plugin was created through the Backstage CLI_ diff --git a/plugins/scaffolder-backend-module-gitea/api-report.md b/plugins/scaffolder-backend-module-gitea/api-report.md new file mode 100644 index 0000000000..51e2f3bd17 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/api-report.md @@ -0,0 +1,20 @@ +## API Report File for "backstage-plugin-scaffolder-backend-module-gitea" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { JsonObject } from '@backstage/types'; +import { TemplateAction } from '@backstage/plugin-scaffolder-node'; + +// @public +export function createAcmeExampleAction(): TemplateAction< + { + myParameter: string; + }, + JsonObject +>; + +// Warnings were encountered during analysis: +// +// src/index.d.ts:2:25 - (tsdoc-characters-after-block-tag) The token "@backstage" looks like a TSDoc tag but contains an invalid character "/"; if it is not a tag, use a backslash to escape the "@" +``` diff --git a/plugins/scaffolder-backend-module-gitea/catalog-info.yaml b/plugins/scaffolder-backend-module-gitea/catalog-info.yaml new file mode 100644 index 0000000000..20511015cd --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/catalog-info.yaml @@ -0,0 +1,9 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-scaffolder-backend-module-gitea + title: 'backstage-plugin-scaffolder-backend-module-gitea' +spec: + lifecycle: experimental + type: backstage-backend-plugin-module + owner: maintainers diff --git a/plugins/scaffolder-backend-module-gitea/package.json b/plugins/scaffolder-backend-module-gitea/package.json new file mode 100644 index 0000000000..9140c294f8 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/package.json @@ -0,0 +1,41 @@ +{ + "name": "backstage-plugin-scaffolder-backend-module-gitea", + "description": "The gitea module for @backstage/plugin-scaffolder-backend", + "version": "0.1.0-next.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/config": "workspace:^", + "@backstage/errors": "workspace:^", + "@backstage/integration": "workspace:^", + "@backstage/plugin-scaffolder-backend": "workspace:^", + "@backstage/plugin-scaffolder-node": "workspace:^", + "node-fetch": "^2.6.7", + "yaml": "^2.0.0" + }, + "devDependencies": { + "@backstage/backend-common": "workspace:^", + "@backstage/cli": "workspace:^" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.ts new file mode 100644 index 0000000000..64d73d498f --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.ts @@ -0,0 +1,158 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: + 'Initializes a Gitea repository of contents in workspace and publish it to Gitea with default configuration.', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + }, + }, + ], + }), + }, + { + description: 'Initializes a Gitea repository with a description.', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + description: 'Initialize a gitea repository', + }, + }, + ], + }), + }, + { + description: + 'Initializes a Gitea repository with a default Branch, if not set defaults to master', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + defaultBranch: 'staging', + }, + }, + ], + }), + }, + { + description: + 'Initializes a Gitea repository with an initial commit message, if not set defaults to initial commit', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + }, + }, + ], + }), + }, + { + description: + 'Initializes a Gitea repository with a repo Author Name, if not set defaults to Scaffolder', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + gitAuthorName: 'John Doe', + }, + }, + ], + }), + }, + { + description: 'Initializes a Gitea repository with a repo Author Email', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + gitAuthorEmail: 'johndoe@email.com', + }, + }, + ], + }), + }, + { + description: + 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + sourcePath: 'repository/', + }, + }, + ], + }), + }, + { + description: 'Initializes a Gitea repository with all properties being set', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + description: 'Initialize a gitea repository', + defaultBranch: 'staging', + gitCommitMessage: 'Initial Commit Message', + gitAuthorName: 'John Doe', + gitAuthorEmail: 'johndoe@email.com', + sourcePath: 'repository/', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts new file mode 100644 index 0000000000..bd40b68603 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts @@ -0,0 +1,49 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { PassThrough } from 'stream'; +import { createAcmeExampleAction } from './gitea'; +import { getVoidLogger } from '@backstage/backend-common'; + +describe('acme:example', () => { + afterEach(() => { + jest.resetAllMocks(); + }); + + it('should call action', async () => { + const action = createAcmeExampleAction(); + + const logger = getVoidLogger(); + jest.spyOn(logger, 'info'); + + await action.handler({ + input: { + myParameter: 'test', + }, + workspacePath: '/tmp', + logger, + logStream: new PassThrough(), + output: jest.fn(), + createTemporaryDirectory() { + // Usage of mock-fs is recommended for testing of filesystem operations + throw new Error('Not implemented'); + }, + }); + + expect(logger.info).toHaveBeenCalledWith( + 'Running example template with parameters: test', + ); + }); +}); diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts new file mode 100644 index 0000000000..a740b4938e --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -0,0 +1,232 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { InputError } from '@backstage/errors'; +import { Config } from '@backstage/config'; +import { + getGiteaRequestOptions, + GiteaIntegrationConfig, + ScmIntegrationRegistry, +} from '@backstage/integration'; +import { + createTemplateAction, + getRepoSourceDirectory, + initRepoAndPush, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; +import { examples } from './gitea.examples'; +import fetch, { RequestInit, Response } from 'node-fetch'; +import crypto from 'crypto'; + +const createGiteaProject = async ( + config: GiteaIntegrationConfig, + options: { + projectName: string; + parent: string; + owner?: string; + description: string; + }, +): Promise => { + const { projectName, parent, owner, description } = options; + + const fetchOptions: RequestInit = { + method: 'PUT', + body: JSON.stringify({ + parent, + description, + owners: owner ? [owner] : [], + create_empty_commit: false, + }), + headers: { + ...getGiteaRequestOptions(config).headers, + 'Content-Type': 'application/json', + }, + }; + + // TODO + const response: Response = await fetch( + `${config.baseUrl}/a/projects/${encodeURIComponent(projectName)}`, + fetchOptions, + ); + if (response.status !== 201) { + throw new Error( + `Unable to create repository, ${response.status} ${ + response.statusText + }, ${await response.text()}`, + ); + } +}; + +const generateCommitMessage = ( + config: Config, + commitSubject?: string, +): string => { + const changeId = crypto.randomBytes(20).toString('hex'); + const msg = `${ + config.getOptionalString('scaffolder.defaultCommitMessage') || commitSubject + }\n\nChange-Id: I${changeId}`; + return msg; +}; + +/** + * Creates a new action that initializes a git repository using the content of the workspace. + * and publishes it to a Gitea instance. + * @public + */ +export function createPublishGiteaAction(options: { + integrations: ScmIntegrationRegistry; + config: Config; +}) { + const { integrations, config } = options; + + return createTemplateAction<{ + repoUrl: string; + description: string; + defaultBranch?: string; + gitCommitMessage?: string; + gitAuthorName?: string; + gitAuthorEmail?: string; + sourcePath?: string; + }>({ + id: 'publish:gitea', + description: + 'Initializes a git repository using the content of the workspace, and publishes it to Gitea.', + examples, + schema: { + input: { + type: 'object', + required: ['repoUrl'], + properties: { + repoUrl: { + title: 'Repository Location', + type: 'string', + }, + description: { + title: 'Repository Description', + type: 'string', + }, + defaultBranch: { + title: 'Default Branch', + type: 'string', + description: `Sets the default branch on the repository. The default value is 'master'`, + }, + gitCommitMessage: { + title: 'Git Commit Message', + type: 'string', + description: `Sets the commit message on the repository. The default value is 'initial commit'`, + }, + gitAuthorName: { + title: 'Default Author Name', + type: 'string', + description: `Sets the default author name for the commit. The default value is 'Scaffolder'`, + }, + gitAuthorEmail: { + title: 'Default Author Email', + type: 'string', + description: `Sets the default author email for the commit.`, + }, + sourcePath: { + title: 'Source Path', + type: 'string', + description: `Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.`, + }, + }, + }, + output: { + type: 'object', + properties: { + remoteUrl: { + title: 'A URL to the repository with the provider', + type: 'string', + }, + repoContentsUrl: { + title: 'A URL to the root of the repository', + type: 'string', + }, + commitHash: { + title: 'The git commit hash of the initial commit', + type: 'string', + }, + }, + }, + }, + async handler(ctx) { + const { + repoUrl, + description, + defaultBranch = 'main', + gitAuthorName, + gitAuthorEmail, + gitCommitMessage = 'initial commit', + sourcePath, + } = ctx.input; + + const { repo, host, owner, workspace } = parseRepoUrl( + repoUrl, + integrations, + ); + + const integrationConfig = integrations.gitea.byHost(host); + + if (!integrationConfig) { + throw new InputError( + `No matching integration configuration for host ${host}, please check your integrations config`, + ); + } + + if (!workspace) { + throw new InputError( + `Invalid URL provider was included in the repo URL to create ${ctx.input.repoUrl}, missing workspace`, + ); + } + + await createGiteaProject(integrationConfig.config, { + description, + owner: owner, + projectName: repo, + parent: workspace, + }); + const auth = { + username: integrationConfig.config.username!, + password: integrationConfig.config.password!, + }; + const gitAuthorInfo = { + name: gitAuthorName + ? gitAuthorName + : config.getOptionalString('scaffolder.defaultAuthor.name'), + email: gitAuthorEmail + ? gitAuthorEmail + : config.getOptionalString('scaffolder.defaultAuthor.email'), + }; + // TODO + const remoteUrl = `${integrationConfig.config.baseUrl}/a/${repo}`; + const commitResult = await initRepoAndPush({ + dir: getRepoSourceDirectory(ctx.workspacePath, sourcePath), + remoteUrl, + auth, + defaultBranch, + logger: ctx.logger, + commitMessage: generateCommitMessage(config, gitCommitMessage), + gitAuthorInfo, + }); + + const repoContentsUrl = `${integrationConfig.config.baseUrl}/${repo}/+/refs/heads/${defaultBranch}`; + ctx.output('remoteUrl', remoteUrl); + ctx.output('commitHash', commitResult?.commitHash); + ctx.output('repoContentsUrl', repoContentsUrl); + }, + }); +} diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/index.ts b/plugins/scaffolder-backend-module-gitea/src/actions/index.ts new file mode 100644 index 0000000000..ccf7f23fab --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/src/actions/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './gitea'; diff --git a/plugins/scaffolder-backend-module-gitea/src/index.ts b/plugins/scaffolder-backend-module-gitea/src/index.ts new file mode 100644 index 0000000000..026da0735a --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/src/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * A module for the scaffolder backend that lets you interact with gitea + * + * @packageDocumentation + */ + +export * from './actions'; diff --git a/yarn.lock b/yarn.lock index 3394871837..065b070197 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22051,6 +22051,22 @@ __metadata: languageName: node linkType: hard +"backstage-plugin-scaffolder-backend-module-gitea@workspace:plugins/scaffolder-backend-module-gitea": + version: 0.0.0-use.local + resolution: "backstage-plugin-scaffolder-backend-module-gitea@workspace:plugins/scaffolder-backend-module-gitea" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/integration": "workspace:^" + "@backstage/plugin-scaffolder-backend": "workspace:^" + "@backstage/plugin-scaffolder-node": "workspace:^" + node-fetch: ^2.6.7 + yaml: ^2.0.0 + languageName: unknown + linkType: soft + "badge-maker@npm:^3.3.0": version: 3.3.1 resolution: "badge-maker@npm:3.3.1" From f6426a32f90d505ca9836eacb1b1dd3b051986e5 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Fri, 15 Dec 2023 15:23:26 +0100 Subject: [PATCH 26/82] WIP. Create action to publish on gitea server Signed-off-by: cmoulliard --- .../src/actions/gitea.examples.ts | 6 +- .../src/actions/gitea.test.ts | 111 ++++++++++++++---- .../src/actions/gitea.ts | 38 +++--- plugins/scaffolder-node/src/actions/util.ts | 4 + 4 files changed, 117 insertions(+), 42 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.ts index 64d73d498f..748a869205 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.ts @@ -20,7 +20,7 @@ import yaml from 'yaml'; export const examples: TemplateExample[] = [ { description: - 'Initializes a Gitea repository of contents in workspace and publish it to Gitea with default configuration.', + 'Initializes a Gitea repository using the content of the workspace and publish it to Gitea with default configuration.', example: yaml.stringify({ steps: [ { @@ -52,7 +52,7 @@ export const examples: TemplateExample[] = [ }, { description: - 'Initializes a Gitea repository with a default Branch, if not set defaults to master', + 'Initializes a Gitea repository with a default Branch, if not set defaults to main', example: yaml.stringify({ steps: [ { @@ -61,7 +61,7 @@ export const examples: TemplateExample[] = [ name: 'Publish to Gitea', input: { repoUrl: 'gitea.com?repo=repo&owner=owner', - defaultBranch: 'staging', + defaultBranch: 'main', }, }, ], diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts index bd40b68603..52a29e2bbc 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts @@ -14,36 +14,103 @@ * limitations under the License. */ import { PassThrough } from 'stream'; -import { createAcmeExampleAction } from './gitea'; +/* import {rest} from 'msw';*/ +import { setupServer } from 'msw'; +import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { ScmIntegrations } from '@backstage/integration'; +import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; +import { createPublishGiteaAction } from './gitea'; +import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; -describe('acme:example', () => { - afterEach(() => { +jest.mock('@backstage/plugin-scaffolder-node', () => { + return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + initRepoAndPush: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + commitAndPushRepo: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + }; +}); + +describe('publish:gitea', () => { + const config = new ConfigReader({ + integrations: { + gitea: [ + { + host: 'gitea.com', + username: 'gitea_user', + password: 'gitea_password', + }, + ], + }, + }); + + const description = 'for the lols'; + const integrations = ScmIntegrations.fromConfig(config); + const action = createPublishGiteaAction({ integrations, config }); + const mockContext = { + input: { + repoUrl: 'gitea.com?repo=repo', + description, + }, + workspacePath: 'lol', + logger: getVoidLogger(), + logStream: new PassThrough(), + output: jest.fn(), + createTemporaryDirectory: jest.fn(), + }; + + const mockGitClient = { + createRepository: jest.fn(), + }; + + const server = setupServer(); + setupRequestMockHandlers(server); + + beforeEach(() => { jest.resetAllMocks(); }); - it('should call action', async () => { - const action = createAcmeExampleAction(); + it('should throw an error when the repoUrl is not well formed', async () => { + await expect( + action.handler({ + ...mockContext, + input: { repoUrl: 'gitea.com?owner=o', description }, + }), + ).rejects.toThrow(/missing repo/); + }); - const logger = getVoidLogger(); - jest.spyOn(logger, 'info'); + it('should throw if there is no integration config provided for missing.com host', async () => { + await expect( + action.handler({ + ...mockContext, + input: { repoUrl: 'missing.com?repo=repo', description }, + }), + ).rejects.toThrow(/No matching integration configuration/); + }); - await action.handler({ - input: { - myParameter: 'test', - }, - workspacePath: '/tmp', - logger, - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory() { - // Usage of mock-fs is recommended for testing of filesystem operations - throw new Error('Not implemented'); - }, + it('should throw if there is no repositoryId returned', async () => { + mockGitClient.createRepository.mockImplementation(() => ({ + remoteUrl: 'https://gitea.com', + id: null, + })); + + await action.handler(mockContext); + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://gitea.com', + defaultBranch: 'main', + auth: { username: 'gitea_user', password: 'gitea_password' }, + logger: mockContext.logger, + commitMessage: 'initial commit', + gitAuthorInfo: {}, }); + }); - expect(logger.info).toHaveBeenCalledWith( - 'Running example template with parameters: test', - ); + afterEach(() => { + jest.resetAllMocks(); }); }); diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index a740b4938e..18e15fc191 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -35,20 +35,19 @@ const createGiteaProject = async ( config: GiteaIntegrationConfig, options: { projectName: string; - parent: string; + // parent: string; owner?: string; description: string; }, ): Promise => { - const { projectName, parent, owner, description } = options; + const { projectName, owner, description } = options; const fetchOptions: RequestInit = { - method: 'PUT', + method: 'POST', body: JSON.stringify({ - parent, + name: projectName, description, - owners: owner ? [owner] : [], - create_empty_commit: false, + owner, }), headers: { ...getGiteaRequestOptions(config).headers, @@ -57,8 +56,10 @@ const createGiteaProject = async ( }; // TODO + // Create a repository in Gitea + // API request: https://gitea.com/api/swagger#/user/createCurrentUserRepo const response: Response = await fetch( - `${config.baseUrl}/a/projects/${encodeURIComponent(projectName)}`, + `${config.baseUrl}/api/v1/user/repos`, fetchOptions, ); if (response.status !== 201) { @@ -174,31 +175,34 @@ export function createPublishGiteaAction(options: { sourcePath, } = ctx.input; - const { repo, host, owner, workspace } = parseRepoUrl( - repoUrl, - integrations, - ); + const { owner, repo, host } = parseRepoUrl(repoUrl, integrations); const integrationConfig = integrations.gitea.byHost(host); - if (!integrationConfig) { throw new InputError( `No matching integration configuration for host ${host}, please check your integrations config`, ); } - if (!workspace) { - throw new InputError( - `Invalid URL provider was included in the repo URL to create ${ctx.input.repoUrl}, missing workspace`, + if ( + !integrationConfig.config.username || + !integrationConfig.config.password + ) { + throw new Error( + 'Credentials for Gitea integration required for this action.', ); } + // TODO + // Check if the integration config includes a baseUrl + await createGiteaProject(integrationConfig.config, { description, owner: owner, projectName: repo, - parent: workspace, + // parent: workspace, }); + const auth = { username: integrationConfig.config.username!, password: integrationConfig.config.password!, @@ -212,7 +216,7 @@ export function createPublishGiteaAction(options: { : config.getOptionalString('scaffolder.defaultAuthor.email'), }; // TODO - const remoteUrl = `${integrationConfig.config.baseUrl}/a/${repo}`; + const remoteUrl = `${integrationConfig.config.baseUrl}/api/v1/user/${repo}`; const commitResult = await initRepoAndPush({ dir: getRepoSourceDirectory(ctx.workspacePath, sourcePath), remoteUrl, diff --git a/plugins/scaffolder-node/src/actions/util.ts b/plugins/scaffolder-node/src/actions/util.ts index 327cfa9c2f..7f7121ef16 100644 --- a/plugins/scaffolder-node/src/actions/util.ts +++ b/plugins/scaffolder-node/src/actions/util.ts @@ -92,6 +92,10 @@ export const parseRepoUrl = ( } break; } + case 'gitea': { + checkRequiredParams(parsed, 'repo'); + break; + } case 'gerrit': { checkRequiredParams(parsed, 'repo'); break; From 49d4e7617ffab6789ac65d88e8de05073275b1a6 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Fri, 15 Dec 2023 15:56:44 +0100 Subject: [PATCH 27/82] Import mising package to create the setupServer. Update yarn.locl and package.json Signed-off-by: cmoulliard --- plugins/scaffolder-backend-module-gitea/package.json | 4 +++- .../scaffolder-backend-module-gitea/src/actions/gitea.test.ts | 3 +-- yarn.lock | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/package.json b/plugins/scaffolder-backend-module-gitea/package.json index 9140c294f8..239146d842 100644 --- a/plugins/scaffolder-backend-module-gitea/package.json +++ b/plugins/scaffolder-backend-module-gitea/package.json @@ -33,7 +33,9 @@ }, "devDependencies": { "@backstage/backend-common": "workspace:^", - "@backstage/cli": "workspace:^" + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts index 52a29e2bbc..ae80f3bdb7 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts @@ -14,14 +14,13 @@ * limitations under the License. */ import { PassThrough } from 'stream'; -/* import {rest} from 'msw';*/ -import { setupServer } from 'msw'; import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; import { createPublishGiteaAction } from './gitea'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; +import { setupServer } from 'msw/node'; jest.mock('@backstage/plugin-scaffolder-node', () => { return { diff --git a/yarn.lock b/yarn.lock index 065b070197..3153025cca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22056,12 +22056,14 @@ __metadata: resolution: "backstage-plugin-scaffolder-backend-module-gitea@workspace:plugins/scaffolder-backend-module-gitea" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-scaffolder-backend": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" + msw: ^1.0.0 node-fetch: ^2.6.7 yaml: ^2.0.0 languageName: unknown From bb0b6568afc6e4d5025a35857976eafd04aaa937 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Fri, 15 Dec 2023 16:48:30 +0100 Subject: [PATCH 28/82] Registering new publish gitea action within createBuiltinActions.ts Signed-off-by: cmoulliard --- .../catalog-info.yaml | 2 +- .../package.json | 2 +- .../actions/builtin/createBuiltinActions.ts | 2 + yarn.lock | 37 ++++++++++--------- 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/catalog-info.yaml b/plugins/scaffolder-backend-module-gitea/catalog-info.yaml index 20511015cd..adfcc754fb 100644 --- a/plugins/scaffolder-backend-module-gitea/catalog-info.yaml +++ b/plugins/scaffolder-backend-module-gitea/catalog-info.yaml @@ -2,7 +2,7 @@ apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: backstage-plugin-scaffolder-backend-module-gitea - title: 'backstage-plugin-scaffolder-backend-module-gitea' + title: '@backstage/plugin-scaffolder-backend-module-gitea' spec: lifecycle: experimental type: backstage-backend-plugin-module diff --git a/plugins/scaffolder-backend-module-gitea/package.json b/plugins/scaffolder-backend-module-gitea/package.json index 239146d842..93dd86e92b 100644 --- a/plugins/scaffolder-backend-module-gitea/package.json +++ b/plugins/scaffolder-backend-module-gitea/package.json @@ -1,5 +1,5 @@ { - "name": "backstage-plugin-scaffolder-backend-module-gitea", + "name": "@backstage/plugin-scaffolder-backend-module-gitea", "description": "The gitea module for @backstage/plugin-scaffolder-backend", "version": "0.1.0-next.0", "main": "src/index.ts", diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts index f9c15597a8..51b2a18a77 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts @@ -75,6 +75,8 @@ import { createPublishGerritReviewAction, } from '@backstage/plugin-scaffolder-backend-module-gerrit'; +import { createPublishGiteaAction } from '@backstage/plugin-scaffolder-backend-module-gitea'; + import { createPublishGitlabAction, createGitlabRepoPushAction, diff --git a/yarn.lock b/yarn.lock index 3153025cca..64bc6fc64e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8492,6 +8492,24 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-scaffolder-backend-module-gitea@workspace:^, @backstage/plugin-scaffolder-backend-module-gitea@workspace:plugins/scaffolder-backend-module-gitea": + version: 0.0.0-use.local + resolution: "@backstage/plugin-scaffolder-backend-module-gitea@workspace:plugins/scaffolder-backend-module-gitea" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/integration": "workspace:^" + "@backstage/plugin-scaffolder-backend": "workspace:^" + "@backstage/plugin-scaffolder-node": "workspace:^" + msw: ^1.0.0 + node-fetch: ^2.6.7 + yaml: ^2.0.0 + languageName: unknown + linkType: soft + "@backstage/plugin-scaffolder-backend-module-github@workspace:^, @backstage/plugin-scaffolder-backend-module-github@workspace:plugins/scaffolder-backend-module-github": version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-github@workspace:plugins/scaffolder-backend-module-github" @@ -8616,6 +8634,7 @@ __metadata: "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "workspace:^" "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "workspace:^" "@backstage/plugin-scaffolder-backend-module-gerrit": "workspace:^" + "@backstage/plugin-scaffolder-backend-module-gitea": "workspace:^" "@backstage/plugin-scaffolder-backend-module-github": "workspace:^" "@backstage/plugin-scaffolder-backend-module-gitlab": "workspace:^" "@backstage/plugin-scaffolder-common": "workspace:^" @@ -22051,24 +22070,6 @@ __metadata: languageName: node linkType: hard -"backstage-plugin-scaffolder-backend-module-gitea@workspace:plugins/scaffolder-backend-module-gitea": - version: 0.0.0-use.local - resolution: "backstage-plugin-scaffolder-backend-module-gitea@workspace:plugins/scaffolder-backend-module-gitea" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-test-utils": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/integration": "workspace:^" - "@backstage/plugin-scaffolder-backend": "workspace:^" - "@backstage/plugin-scaffolder-node": "workspace:^" - msw: ^1.0.0 - node-fetch: ^2.6.7 - yaml: ^2.0.0 - languageName: unknown - linkType: soft - "badge-maker@npm:^3.3.0": version: 3.3.1 resolution: "badge-maker@npm:3.3.1" From b2953bd1085c85eb84240560cddd383a9c284a07 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Fri, 15 Dec 2023 17:02:14 +0100 Subject: [PATCH 29/82] Update package.json to add gitea module Signed-off-by: cmoulliard --- plugins/scaffolder-backend/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 9026761a7c..858591749c 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -64,6 +64,7 @@ "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "workspace:^", "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "workspace:^", "@backstage/plugin-scaffolder-backend-module-gerrit": "workspace:^", + "@backstage/plugin-scaffolder-backend-module-gitea": "workspace:^", "@backstage/plugin-scaffolder-backend-module-github": "workspace:^", "@backstage/plugin-scaffolder-backend-module-gitlab": "workspace:^", "@backstage/plugin-scaffolder-common": "workspace:^", From f1645f3e0a4649866775658f37306b102b9396c4 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Fri, 15 Dec 2023 18:19:39 +0100 Subject: [PATCH 30/82] Register the missing gitea action to publish Signed-off-by: cmoulliard --- .../scaffolder/actions/builtin/createBuiltinActions.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts index 51b2a18a77..2ee0a7644f 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts @@ -75,14 +75,14 @@ import { createPublishGerritReviewAction, } from '@backstage/plugin-scaffolder-backend-module-gerrit'; -import { createPublishGiteaAction } from '@backstage/plugin-scaffolder-backend-module-gitea'; - import { createPublishGitlabAction, createGitlabRepoPushAction, createPublishGitlabMergeRequestAction, } from '@backstage/plugin-scaffolder-backend-module-gitlab'; +import { createPublishGiteaAction } from '@backstage/plugin-scaffolder-backend-module-gitea'; + /** * The options passed to {@link createBuiltinActions} * @public @@ -160,6 +160,10 @@ export const createBuiltinActions = ( integrations, config, }), + createPublishGiteaAction({ + integrations, + config, + }), createPublishGithubAction({ integrations, config, From f8afc5c059abf9ee3ce02e9ece15526c1fb09dff Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Tue, 19 Dec 2023 14:58:08 +0100 Subject: [PATCH 31/82] Align default branch name. master -> main Signed-off-by: cmoulliard --- plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index 18e15fc191..011be04fc1 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -122,7 +122,7 @@ export function createPublishGiteaAction(options: { defaultBranch: { title: 'Default Branch', type: 'string', - description: `Sets the default branch on the repository. The default value is 'master'`, + description: `Sets the default branch on the repository. The default value is 'main'`, }, gitCommitMessage: { title: 'Git Commit Message', From a37b65c79ee3343282d3dd666141b28cb7bd0dfd Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Tue, 19 Dec 2023 15:00:47 +0100 Subject: [PATCH 32/82] Reverted name cgange from gitea.tst to example.ts, example.test.ts Signed-off-by: cmoulliard --- packages/cli/src/lib/new/factories/scaffolderModule.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/lib/new/factories/scaffolderModule.test.ts b/packages/cli/src/lib/new/factories/scaffolderModule.test.ts index 767ae0fc44..b43946228b 100644 --- a/packages/cli/src/lib/new/factories/scaffolderModule.test.ts +++ b/packages/cli/src/lib/new/factories/scaffolderModule.test.ts @@ -77,8 +77,8 @@ describe('scaffolderModule factory', () => { 'templating package.json.hbs', 'templating index.ts.hbs', 'copying index.ts', - 'copying gitea.test.ts', - 'copying gitea.ts', + 'copying example.test.ts', + 'copying example.ts', 'copying index.ts', 'Installing:', `moving plugins${sep}scaffolder-backend-module-test`, From 4d2c01bfbff613825ace8449559529a78e56fa1e Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Tue, 19 Dec 2023 15:02:25 +0100 Subject: [PATCH 33/82] Changing the version from 0.1.0-next.0 to 0.0.0 Signed-off-by: cmoulliard --- plugins/scaffolder-backend-module-gitea/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend-module-gitea/package.json b/plugins/scaffolder-backend-module-gitea/package.json index 93dd86e92b..c9e9a4e07d 100644 --- a/plugins/scaffolder-backend-module-gitea/package.json +++ b/plugins/scaffolder-backend-module-gitea/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gitea", "description": "The gitea module for @backstage/plugin-scaffolder-backend", - "version": "0.1.0-next.0", + "version": "0.0.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", From 827d88fce12dab230882a009f5104843b194ad7d Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Tue, 19 Dec 2023 15:03:42 +0100 Subject: [PATCH 34/82] Removing the CHANGELOG.md file as the releasing flow will create it Signed-off-by: cmoulliard --- plugins/scaffolder-backend-module-gitea/CHANGELOG.md | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 plugins/scaffolder-backend-module-gitea/CHANGELOG.md diff --git a/plugins/scaffolder-backend-module-gitea/CHANGELOG.md b/plugins/scaffolder-backend-module-gitea/CHANGELOG.md deleted file mode 100644 index a4f1f20179..0000000000 --- a/plugins/scaffolder-backend-module-gitea/CHANGELOG.md +++ /dev/null @@ -1,7 +0,0 @@ -# @backstage/plugin-scaffolder-backend-module-gitea - -## 0.1.0-next.0 - -### Minor Changes - -- TODO: Add Gitea Scaffolder Plugin From 11d697be7709e43d46417e7a8afe55c2bf3adc40 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Tue, 19 Dec 2023 15:12:41 +0100 Subject: [PATCH 35/82] Updating the api-report.md file Signed-off-by: cmoulliard --- .../api-report.md | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/api-report.md b/plugins/scaffolder-backend-module-gitea/api-report.md index 51e2f3bd17..f83ae73fb7 100644 --- a/plugins/scaffolder-backend-module-gitea/api-report.md +++ b/plugins/scaffolder-backend-module-gitea/api-report.md @@ -1,20 +1,27 @@ -## API Report File for "backstage-plugin-scaffolder-backend-module-gitea" +## API Report File for "@backstage/plugin-scaffolder-backend-module-gitea" > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { Config } from '@backstage/config'; import { JsonObject } from '@backstage/types'; +import { ScmIntegrationRegistry } from '@backstage/integration'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; // @public -export function createAcmeExampleAction(): TemplateAction< +export function createPublishGiteaAction(options: { + integrations: ScmIntegrationRegistry; + config: Config; +}): TemplateAction< { - myParameter: string; + repoUrl: string; + description: string; + defaultBranch?: string | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + sourcePath?: string | undefined; }, JsonObject >; - -// Warnings were encountered during analysis: -// -// src/index.d.ts:2:25 - (tsdoc-characters-after-block-tag) The token "@backstage" looks like a TSDoc tag but contains an invalid character "/"; if it is not a tag, use a backslash to escape the "@" ``` From 90836c82e4f0cdecd3a210c02bfe91e8e9793380 Mon Sep 17 00:00:00 2001 From: Charles Moulliard Date: Tue, 19 Dec 2023 15:23:37 +0100 Subject: [PATCH 36/82] Update plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Signed-off-by: Charles Moulliard Signed-off-by: cmoulliard --- plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index 011be04fc1..7b6547b30d 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -169,8 +169,8 @@ export function createPublishGiteaAction(options: { repoUrl, description, defaultBranch = 'main', - gitAuthorName, - gitAuthorEmail, + gitAuthorName = config.getOptionalString('scaffolder.defaultAuthor.name'), + gitAuthorEmail = config.getOptionalString('scaffolder.defaultAuthor.email'), gitCommitMessage = 'initial commit', sourcePath, } = ctx.input; From 3e20f53e49e2c26d10042d3f04ce6c3be3cea131 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 20 Dec 2023 09:36:09 +0100 Subject: [PATCH 37/82] Rename basic to Basic Signed-off-by: cmoulliard --- packages/integration/src/gitea/core.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/integration/src/gitea/core.ts b/packages/integration/src/gitea/core.ts index 95caa24c06..6d11a4ffde 100644 --- a/packages/integration/src/gitea/core.ts +++ b/packages/integration/src/gitea/core.ts @@ -120,7 +120,7 @@ export function getGiteaRequestOptions(config: GiteaIntegrationConfig): { } if (username) { - headers.Authorization = `basic ${Buffer.from( + headers.Authorization = `Basic ${Buffer.from( `${username}:${password}`, ).toString('base64')}`; } else { From 07bd2fbeb43259acd8c8b64f2601b264b47d3164 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 20 Dec 2023 09:40:08 +0100 Subject: [PATCH 38/82] Rename token to Token Signed-off-by: cmoulliard --- packages/integration/src/gitea/core.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/integration/src/gitea/core.ts b/packages/integration/src/gitea/core.ts index 6d11a4ffde..f188613d2a 100644 --- a/packages/integration/src/gitea/core.ts +++ b/packages/integration/src/gitea/core.ts @@ -124,7 +124,7 @@ export function getGiteaRequestOptions(config: GiteaIntegrationConfig): { `${username}:${password}`, ).toString('base64')}`; } else { - headers.Authorization = `token ${password}`; + headers.Authorization = `Token ${password}`; } return { From 51fec95f3340c20d772a73add9d28e748ef08a96 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 20 Dec 2023 10:52:28 +0100 Subject: [PATCH 39/82] Add test to valid the baseURL Signed-off-by: cmoulliard --- packages/integration/src/gitea/config.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/integration/src/gitea/config.ts b/packages/integration/src/gitea/config.ts index 28070d570d..ae1fe5ee87 100644 --- a/packages/integration/src/gitea/config.ts +++ b/packages/integration/src/gitea/config.ts @@ -16,7 +16,7 @@ import { Config } from '@backstage/config'; import { trimEnd } from 'lodash'; -import { isValidHost } from '../helpers'; +import { isValidHost, isValidUrl } from '../helpers'; /** * The configuration for a single Gitea integration. @@ -62,6 +62,10 @@ export function readGiteaConfig(config: Config): GiteaIntegrationConfig { throw new Error( `Invalid Gitea integration config, '${host}' is not a valid host`, ); + } else if (baseUrl && !isValidUrl(baseUrl)) { + throw new Error( + `Invalid Gitea integration config, '${baseUrl}' is not a valid baseUrl`, + ); } if (baseUrl) { From 1c91c52a096f95a0479eefbbbc98d0be46cca52d Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 20 Dec 2023 10:53:00 +0100 Subject: [PATCH 40/82] Updating the test case to create a git repo Signed-off-by: cmoulliard --- .../src/actions/gitea.test.ts | 46 +++++++++++++------ .../src/actions/gitea.ts | 1 - 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts index ae80f3bdb7..6461726dcf 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts @@ -14,12 +14,13 @@ * limitations under the License. */ import { PassThrough } from 'stream'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; import { createPublishGiteaAction } from './gitea'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; +import { rest } from 'msw'; +import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; import { setupServer } from 'msw/node'; jest.mock('@backstage/plugin-scaffolder-node', () => { @@ -28,9 +29,6 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { initRepoAndPush: jest.fn().mockResolvedValue({ commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', }), - commitAndPushRepo: jest.fn().mockResolvedValue({ - commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', - }), }; }); @@ -40,6 +38,7 @@ describe('publish:gitea', () => { gitea: [ { host: 'gitea.com', + baseUrl: 'https://gitea.com', username: 'gitea_user', password: 'gitea_password', }, @@ -52,7 +51,7 @@ describe('publish:gitea', () => { const action = createPublishGiteaAction({ integrations, config }); const mockContext = { input: { - repoUrl: 'gitea.com?repo=repo', + repoUrl: 'gitea.com?repo=repo&owner=owner', description, }, workspacePath: 'lol', @@ -62,10 +61,6 @@ describe('publish:gitea', () => { createTemporaryDirectory: jest.fn(), }; - const mockGitClient = { - createRepository: jest.fn(), - }; - const server = setupServer(); setupRequestMockHandlers(server); @@ -92,15 +87,36 @@ describe('publish:gitea', () => { }); it('should throw if there is no repositoryId returned', async () => { - mockGitClient.createRepository.mockImplementation(() => ({ - remoteUrl: 'https://gitea.com', - id: null, - })); + server.use( + rest.put('https://gitea.com/api/v1/user/repo', (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe( + 'Basic Z2l0ZWFfdXNlcjpnaXRlYV9wYXNzd29yZA==', + ); + expect(req.body).toEqual({ + create_empty_commit: false, + owners: ['owner'], + description, + parent: 'workspace', + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }), + ); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + repoUrl: 'gitea.com?owner=owner&repo=repo', + }, + }); - await action.handler(mockContext); expect(initRepoAndPush).toHaveBeenCalledWith({ dir: mockContext.workspacePath, - remoteUrl: 'https://gitea.com', + remoteUrl: 'https://gitea.com/api/v1/user/repo', defaultBranch: 'main', auth: { username: 'gitea_user', password: 'gitea_password' }, logger: mockContext.logger, diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index 7b6547b30d..0c7a5113ee 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -47,7 +47,6 @@ const createGiteaProject = async ( body: JSON.stringify({ name: projectName, description, - owner, }), headers: { ...getGiteaRequestOptions(config).headers, From 331c4c242ac438cb0edfcd5d9c62b2b83447071e Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 20 Dec 2023 11:49:55 +0100 Subject: [PATCH 41/82] Try catch the method calling fetch Signed-off-by: cmoulliard --- .../src/actions/gitea.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index 0c7a5113ee..03f3ce27e2 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -57,10 +57,12 @@ const createGiteaProject = async ( // TODO // Create a repository in Gitea // API request: https://gitea.com/api/swagger#/user/createCurrentUserRepo - const response: Response = await fetch( - `${config.baseUrl}/api/v1/user/repos`, - fetchOptions, - ); + let response: Response; + try { + response = await fetch(`${config.baseUrl}/api/v1/user/repos`, fetchOptions); + } catch (e) { + throw new Error(`Unable to create repository, ${e}`); + } if (response.status !== 201) { throw new Error( `Unable to create repository, ${response.status} ${ @@ -168,8 +170,12 @@ export function createPublishGiteaAction(options: { repoUrl, description, defaultBranch = 'main', - gitAuthorName = config.getOptionalString('scaffolder.defaultAuthor.name'), - gitAuthorEmail = config.getOptionalString('scaffolder.defaultAuthor.email'), + gitAuthorName = config.getOptionalString( + 'scaffolder.defaultAuthor.name', + ), + gitAuthorEmail = config.getOptionalString( + 'scaffolder.defaultAuthor.email', + ), gitCommitMessage = 'initial commit', sourcePath, } = ctx.input; From 38ebfd198044d433b27531084e181913f4371fd8 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 20 Dec 2023 12:00:48 +0100 Subject: [PATCH 42/82] Remove non needed declarations Signed-off-by: cmoulliard --- .../scaffolder-backend-module-gitea/src/actions/gitea.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index 03f3ce27e2..a68f92592e 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -170,12 +170,8 @@ export function createPublishGiteaAction(options: { repoUrl, description, defaultBranch = 'main', - gitAuthorName = config.getOptionalString( - 'scaffolder.defaultAuthor.name', - ), - gitAuthorEmail = config.getOptionalString( - 'scaffolder.defaultAuthor.email', - ), + gitAuthorName, + gitAuthorEmail, gitCommitMessage = 'initial commit', sourcePath, } = ctx.input; From 31e0e51bb99fb05077a65c6692767670d7971761 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 20 Dec 2023 12:05:20 +0100 Subject: [PATCH 43/82] Fix url typo error: ../repo => ../repos Signed-off-by: cmoulliard --- .../scaffolder-backend-module-gitea/src/actions/gitea.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts index 6461726dcf..6290b2b33d 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts @@ -88,7 +88,7 @@ describe('publish:gitea', () => { it('should throw if there is no repositoryId returned', async () => { server.use( - rest.put('https://gitea.com/api/v1/user/repo', (req, res, ctx) => { + rest.post('https://gitea.com/api/v1/user/repos', (req, res, ctx) => { expect(req.headers.get('Authorization')).toBe( 'Basic Z2l0ZWFfdXNlcjpnaXRlYV9wYXNzd29yZA==', ); From 3bff96fc389c8983a66603983a9a60e4462d87f2 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 20 Dec 2023 14:25:30 +0100 Subject: [PATCH 44/82] Fixing matching condition Signed-off-by: cmoulliard --- .../src/actions/gitea.test.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts index 6290b2b33d..4be82a0e12 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts @@ -38,7 +38,6 @@ describe('publish:gitea', () => { gitea: [ { host: 'gitea.com', - baseUrl: 'https://gitea.com', username: 'gitea_user', password: 'gitea_password', }, @@ -93,10 +92,8 @@ describe('publish:gitea', () => { 'Basic Z2l0ZWFfdXNlcjpnaXRlYV9wYXNzd29yZA==', ); expect(req.body).toEqual({ - create_empty_commit: false, - owners: ['owner'], + name: 'repo', description, - parent: 'workspace', }); return res( ctx.status(201), @@ -120,8 +117,11 @@ describe('publish:gitea', () => { defaultBranch: 'main', auth: { username: 'gitea_user', password: 'gitea_password' }, logger: mockContext.logger, - commitMessage: 'initial commit', - gitAuthorInfo: {}, + commitMessage: expect.stringContaining('initial commit\n\nChange-Id:'), + gitAuthorInfo: { + email: undefined, + name: undefined, + }, }); }); From 3a40f3c5dfc2bbc746efbd4106c0481f184fb302 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 20 Dec 2023 16:59:50 +0100 Subject: [PATCH 45/82] Removing owner as non needed Signed-off-by: cmoulliard --- .../src/actions/gitea.test.ts | 3 ++- .../scaffolder-backend-module-gitea/src/actions/gitea.ts | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts index 4be82a0e12..ee0457cac0 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts @@ -88,6 +88,7 @@ describe('publish:gitea', () => { it('should throw if there is no repositoryId returned', async () => { server.use( rest.post('https://gitea.com/api/v1/user/repos', (req, res, ctx) => { + // Basic auth must match the user and password defined part of the config expect(req.headers.get('Authorization')).toBe( 'Basic Z2l0ZWFfdXNlcjpnaXRlYV9wYXNzd29yZA==', ); @@ -107,7 +108,7 @@ describe('publish:gitea', () => { ...mockContext, input: { ...mockContext.input, - repoUrl: 'gitea.com?owner=owner&repo=repo', + repoUrl: 'gitea.com?repo=repo', }, }); diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index a68f92592e..cc16359d75 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -40,7 +40,7 @@ const createGiteaProject = async ( description: string; }, ): Promise => { - const { projectName, owner, description } = options; + const { projectName, description } = options; const fetchOptions: RequestInit = { method: 'POST', @@ -176,7 +176,7 @@ export function createPublishGiteaAction(options: { sourcePath, } = ctx.input; - const { owner, repo, host } = parseRepoUrl(repoUrl, integrations); + const { repo, host } = parseRepoUrl(repoUrl, integrations); const integrationConfig = integrations.gitea.byHost(host); if (!integrationConfig) { @@ -199,7 +199,7 @@ export function createPublishGiteaAction(options: { await createGiteaProject(integrationConfig.config, { description, - owner: owner, + // owner: owner, projectName: repo, // parent: workspace, }); From 701eefc71eb3aa22535e51e06fb3d3e9e79721e7 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 3 Jan 2024 15:18:58 +0100 Subject: [PATCH 46/82] Switched the logic to create a repository using api/v1/orgs/OWNER/repos. Adapt the test case to check if there is an org too Signed-off-by: cmoulliard --- packages/integration/src/gitea/core.ts | 1 + .../src/actions/gitea.test.ts | 19 ++++- .../src/actions/gitea.ts | 75 ++++++++++++++----- 3 files changed, 75 insertions(+), 20 deletions(-) diff --git a/packages/integration/src/gitea/core.ts b/packages/integration/src/gitea/core.ts index f188613d2a..40f1c0fb6d 100644 --- a/packages/integration/src/gitea/core.ts +++ b/packages/integration/src/gitea/core.ts @@ -14,6 +14,7 @@ * limitations under the License. */ import { GiteaIntegrationConfig } from './config'; +import { Logger } from 'winston'; /** * Given a URL pointing to a file, returns a URL diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts index ee0457cac0..5486b5b69f 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts @@ -87,7 +87,20 @@ describe('publish:gitea', () => { it('should throw if there is no repositoryId returned', async () => { server.use( - rest.post('https://gitea.com/api/v1/user/repos', (req, res, ctx) => { + rest.get('https://gitea.com/api/v1/orgs/org1', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + id: 1, + name: 'org1', + visibility: 'public', + repo_admin_change_team_access: false, + username: 'org1', + }), + ); + }), + rest.post('https://gitea.com/api/v1/orgs/org1/repos', (req, res, ctx) => { // Basic auth must match the user and password defined part of the config expect(req.headers.get('Authorization')).toBe( 'Basic Z2l0ZWFfdXNlcjpnaXRlYV9wYXNzd29yZA==', @@ -108,13 +121,13 @@ describe('publish:gitea', () => { ...mockContext, input: { ...mockContext.input, - repoUrl: 'gitea.com?repo=repo', + repoUrl: 'gitea.com?repo=repo&owner=org1', }, }); expect(initRepoAndPush).toHaveBeenCalledWith({ dir: mockContext.workspacePath, - remoteUrl: 'https://gitea.com/api/v1/user/repo', + remoteUrl: 'https://gitea.com/org1/repo.git', defaultBranch: 'main', auth: { username: 'gitea_user', password: 'gitea_password' }, logger: mockContext.logger, diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index cc16359d75..b11d5bf765 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -31,18 +31,60 @@ import { examples } from './gitea.examples'; import fetch, { RequestInit, Response } from 'node-fetch'; import crypto from 'crypto'; +const checkGiteaOrg = async ( + config: GiteaIntegrationConfig, + options: { + owner: string; + }, +): Promise => { + const { owner } = options; + let response: Response; + // check first if the org = owner exists + const getOptions: RequestInit = { + method: 'GET', + headers: { + ...getGiteaRequestOptions(config).headers, + 'Content-Type': 'application/json', + }, + }; + try { + response = await fetch( + `${config.baseUrl}/api/v1/orgs/${owner}`, + getOptions, + ); + } catch (e) { + throw new Error(`Unable to get the Organization: ${owner}, ${e}`); + } + if (response.status !== 200) { + throw new Error( + `Organization ${owner} do not exist. Please create it first !`, + ); + } +}; + const createGiteaProject = async ( config: GiteaIntegrationConfig, options: { projectName: string; - // parent: string; owner?: string; description: string; }, ): Promise => { - const { projectName, description } = options; + const { projectName, description, owner } = options; - const fetchOptions: RequestInit = { + /* + Several options exist to create a repository using either the user or organisation + User: https://gitea.com/api/swagger#/user/createCurrentUserRepo + Api: URL/api/v1/user/repos + Remark: The user is the username defined part of the backstage integration config for the gitea URL ! + + Org: https://gitea.com/api/swagger#/organization/createOrgRepo + Api: URL/api/v1/orgs/${org_owner}/repos + This is the default scenario that we support currently + */ + let response: Response; + + const postOptions: RequestInit = { method: 'POST', body: JSON.stringify({ name: projectName, @@ -53,13 +95,11 @@ const createGiteaProject = async ( 'Content-Type': 'application/json', }, }; - - // TODO - // Create a repository in Gitea - // API request: https://gitea.com/api/swagger#/user/createCurrentUserRepo - let response: Response; try { - response = await fetch(`${config.baseUrl}/api/v1/user/repos`, fetchOptions); + response = await fetch( + `${config.baseUrl}/api/v1/orgs/${owner}/repos`, + postOptions, + ); } catch (e) { throw new Error(`Unable to create repository, ${e}`); } @@ -176,7 +216,7 @@ export function createPublishGiteaAction(options: { sourcePath, } = ctx.input; - const { repo, host } = parseRepoUrl(repoUrl, integrations); + const { repo, host, owner } = parseRepoUrl(repoUrl, integrations); const integrationConfig = integrations.gitea.byHost(host); if (!integrationConfig) { @@ -194,14 +234,15 @@ export function createPublishGiteaAction(options: { ); } - // TODO - // Check if the integration config includes a baseUrl + // check if the org exists within the gitea server + if (owner) { + await checkGiteaOrg(integrationConfig.config, { owner }); + } await createGiteaProject(integrationConfig.config, { description, - // owner: owner, + owner: owner, projectName: repo, - // parent: workspace, }); const auth = { @@ -216,8 +257,8 @@ export function createPublishGiteaAction(options: { ? gitAuthorEmail : config.getOptionalString('scaffolder.defaultAuthor.email'), }; - // TODO - const remoteUrl = `${integrationConfig.config.baseUrl}/api/v1/user/${repo}`; + // The owner to be used should be either the org name or user authenticated with the gitea server + const remoteUrl = `${integrationConfig.config.baseUrl}/${owner}/${repo}.git`; const commitResult = await initRepoAndPush({ dir: getRepoSourceDirectory(ctx.workspacePath, sourcePath), remoteUrl, @@ -228,7 +269,7 @@ export function createPublishGiteaAction(options: { gitAuthorInfo, }); - const repoContentsUrl = `${integrationConfig.config.baseUrl}/${repo}/+/refs/heads/${defaultBranch}`; + const repoContentsUrl = `${integrationConfig.config.baseUrl}/${owner}/${repo}/+/refs/${defaultBranch}`; ctx.output('remoteUrl', remoteUrl); ctx.output('commitHash', commitResult?.commitHash); ctx.output('repoContentsUrl', repoContentsUrl); From 17235fcaec32d047a64182c958aae5e4eab66bb3 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 3 Jan 2024 17:03:10 +0100 Subject: [PATCH 47/82] Removing the non needed import for logger Signed-off-by: cmoulliard --- packages/integration/src/gitea/core.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/integration/src/gitea/core.ts b/packages/integration/src/gitea/core.ts index 40f1c0fb6d..f188613d2a 100644 --- a/packages/integration/src/gitea/core.ts +++ b/packages/integration/src/gitea/core.ts @@ -14,7 +14,6 @@ * limitations under the License. */ import { GiteaIntegrationConfig } from './config'; -import { Logger } from 'winston'; /** * Given a URL pointing to a file, returns a URL From ca0ac99493605b1657f975b0a47103a38495097d Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 3 Jan 2024 17:04:08 +0100 Subject: [PATCH 48/82] Add a sleep of 2s to let the step to register the newly catalog created from the gitea server Signed-off-by: cmoulliard --- plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index b11d5bf765..e8c7328245 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -216,6 +216,8 @@ export function createPublishGiteaAction(options: { sourcePath, } = ctx.input; + const sleep = (ms: number | undefined) => + new Promise(r => setTimeout(r, ms)); const { repo, host, owner } = parseRepoUrl(repoUrl, integrations); const integrationConfig = integrations.gitea.byHost(host); @@ -269,6 +271,9 @@ export function createPublishGiteaAction(options: { gitAuthorInfo, }); + // TODO: As mentioned by Ben lambert, we should poll an endpoint to see if it's ready yet instead of hard coding a sleep + await sleep(2000); + const repoContentsUrl = `${integrationConfig.config.baseUrl}/${owner}/${repo}/+/refs/${defaultBranch}`; ctx.output('remoteUrl', remoteUrl); ctx.output('commitHash', commitResult?.commitHash); From 8a88e91817f79258e6392acbd79338cb38856e7d Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 4 Jan 2024 09:54:00 +0100 Subject: [PATCH 49/82] Switched the sleep 3s to a while condition to check if we got from the repository created the metadata Signed-off-by: cmoulliard --- .../src/actions/gitea.ts | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index e8c7328245..50b215f7d8 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -31,6 +31,36 @@ import { examples } from './gitea.examples'; import fetch, { RequestInit, Response } from 'node-fetch'; import crypto from 'crypto'; +const checkGiteaOrgRepo = async ( + config: GiteaIntegrationConfig, + options: { + owner?: string; + repo: string; + defaultBranch?: string; + }, +): Promise => { + const { owner, repo, defaultBranch } = options; + let response: Response; + const getOptions: RequestInit = { + method: 'GET', + headers: { + ...getGiteaRequestOptions(config).headers, + 'Content-Type': 'application/json', + }, + }; + + try { + response = await fetch( + `${config.baseUrl}/api/v1/repos/${owner}/${repo}/contents?ref=${defaultBranch}`, + getOptions, + ); + } catch (e) { + throw new Error( + `Unable to get the repository: ${owner}/${repo} metadata , ${e}`, + ); + } + return response; +}; const checkGiteaOrg = async ( config: GiteaIntegrationConfig, options: { @@ -218,6 +248,7 @@ export function createPublishGiteaAction(options: { const sleep = (ms: number | undefined) => new Promise(r => setTimeout(r, ms)); + const { repo, host, owner } = parseRepoUrl(repoUrl, integrations); const integrationConfig = integrations.gitea.byHost(host); @@ -271,8 +302,21 @@ export function createPublishGiteaAction(options: { gitAuthorInfo, }); - // TODO: As mentioned by Ben lambert, we should poll an endpoint to see if it's ready yet instead of hard coding a sleep - await sleep(2000); + // Check if the repo is available + let response: Response; + response = await checkGiteaOrgRepo(integrationConfig.config, { + owner, + repo, + defaultBranch, + }); + while (response.status !== 200) { + await sleep(1000); + response = await checkGiteaOrgRepo(integrationConfig.config, { + owner, + repo, + defaultBranch, + }); + } const repoContentsUrl = `${integrationConfig.config.baseUrl}/${owner}/${repo}/+/refs/${defaultBranch}`; ctx.output('remoteUrl', remoteUrl); From 458bf21b7f10bdad8ed2559c8f1c70d1d15773a7 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 4 Jan 2024 14:01:05 +0100 Subject: [PATCH 50/82] Added a new changeSet Signed-off-by: cmoulliard --- .changeset/metal-clocks-suffer.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/metal-clocks-suffer.md diff --git a/.changeset/metal-clocks-suffer.md b/.changeset/metal-clocks-suffer.md new file mode 100644 index 0000000000..f94deb380c --- /dev/null +++ b/.changeset/metal-clocks-suffer.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitea': minor +'@backstage/plugin-scaffolder-backend': minor +'@backstage/plugin-scaffolder-node': minor +'@backstage/integration': patch +--- + +Added support to create a git repository and publish a scaffolded project using a new action "publish:gitea" for gitea. The action currently supports to create a gitea org's repository - https://gitea.com/api/swagger#/organization/createOrgRepo From 39bc3d0d7d0913dc7ffc41a5fe103485f35ae5f1 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 4 Jan 2024 14:54:41 +0100 Subject: [PATCH 51/82] Updated the instructions to use the publish:gitea action Signed-off-by: cmoulliard --- .../scaffolder-backend-module-gitea/README.md | 162 +++++++++++++++++- 1 file changed, 159 insertions(+), 3 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/README.md b/plugins/scaffolder-backend-module-gitea/README.md index 84b8ab6ea5..9d733e76ff 100644 --- a/plugins/scaffolder-backend-module-gitea/README.md +++ b/plugins/scaffolder-backend-module-gitea/README.md @@ -1,5 +1,161 @@ -# backstage-plugin-scaffolder-backend-module-gitea +# scaffolder-backend-module-gitea -The gitea module for [@backstage/plugin-scaffolder-backend](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend). +Welcome to the `publish:gitea` action of the `scaffolder-gitea-backend`. -_This plugin was created through the Backstage CLI_ +## Getting started + +To use this action, you will have to add the package using the following command to be executed at the root of your backstage project: + +```bash +yarn add --cwd packages/backend +@backstage/plugin-scaffolder-backend-module-gitea +``` + +Configure the action (if not yet done): +(you can check the [docs](https://backstage.io/docs/features/software-templates/writing-custom-actions#registering-custom-actions) to see all options): + +```typescript +// plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts + +export const createBuiltinActions = ( +... + const actions = [ + ... + createPublishGiteaAction({ + integrations, + config, + }), + ... + ]; + return actions as TemplateAction[]; +}; +``` + +Before to create a template, include to your `app-config.yaml` file the +gitea host and credentials under the `integrations:` section + +```yaml +integrations: + gitea: + - host: gitea.com + username: '' + password: '' + - host: localhost:3333 + username: '' + password: '' +``` + +**NOTE**: As backstage will issue HTTPS/TLS requests to the gitea instance, it is needed to configure `gitea` with a valid certificate or at least with a +self-signed certificate `gitea cert --host localhost -ca`. Don't forget to set the env var `NODE_EXTRA_CA_CERTS` to point to the CA pem file before to launch backstage ! + +When done, you can use the action in your template: + +```yaml +apiVersion: scaffolder.backstage.io/v1beta3 +kind: Template +metadata: + name: quarkus-web-template + title: Quarkus Hello world + description: Create a simple microservice using Quarkus + tags: + - java + - quarkus +spec: + owner: quarkus + type: service + parameters: + - title: Provide Information for Application + required: + - component_id + - owner + - java_package_name + properties: + component_id: + title: Name + type: string + description: Unique name of the component + default: my-quarkus-app + ui:field: EntityNamePicker + group_id: + title: Group Id + type: string + default: io.quarkus + description: Maven Group Id + artifact_id: + title: Artifact Id + type: string + default: quarkus-app + description: Maven Artifact Id + java_package_name: + title: Java Package Name + default: io.quarkus.demo + type: string + description: Name for the java package. eg (io.quarkus.blah) + owner: + title: Owner + type: string + description: IdP owner of the component + ui:field: OwnerPicker + ui:options: + allowedKinds: + - Group + + - title: Application git repository Information + required: + - repoUrl + properties: + repoUrl: + title: Repository Location + type: string + ui:field: RepoUrlPicker + ui:options: + allowedHosts: + - localhost:3333 + - gitea.: + + steps: + - id: template + name: Generating component + action: fetch:template + input: + url: ./skeleton + copyWithoutTemplating: + - .github/workflows/* + values: + component_id: ${{ parameters.component_id }} + namespace: ${{ parameters.component_id }}-dev + description: ${{ parameters.description }} + group_id: ${{ parameters.group_id }} + artifact_id: ${{ parameters.artifact_id }} + java_package_name: ${{ parameters.java_package_name }} + owner: ${{ parameters.owner }} + destination: ${{ (parameters.repoUrl | parseRepoUrl).owner }}/${{ (parameters.repoUrl | parseRepoUrl).repo }} + quay_destination: ${{ parameters.image_organization }}/${{ parameters.component_id }} + port: 8080 + + - id: publish + name: Publishing to a gitea git repository + action: publish:gitea + input: + description: This is ${{ parameters.component_id }} + repoUrl: ${{ parameters.repoUrl }} + defaultBranch: main + + - id: register + if: ${{ parameters.dryRun !== true }} + name: Register + action: catalog:register + input: + repoContentsUrl: ${{ steps['publish'].output.repoContentsUrl }} + catalogInfoPath: '/catalog-info.yaml' + + output: + links: + - title: Source Code Repository + url: ${{ steps.publish.output.remoteUrl }} + - title: Open Component in catalog + icon: catalog + entityRef: ${{ steps.register.output.entityRef }} +``` + +Enjoy ;-) From 1a49b1d137bdbe2ae46e98eb1320bf439e095211 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 4 Jan 2024 18:16:26 +0100 Subject: [PATCH 52/82] Added a TODO task as the code using while condition is failing like a mention to pass the branch name to the catalogInfoPath Signed-off-by: cmoulliard --- plugins/scaffolder-backend-module-gitea/README.md | 4 +++- .../src/actions/gitea.ts | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend-module-gitea/README.md b/plugins/scaffolder-backend-module-gitea/README.md index 9d733e76ff..6b42eca9d0 100644 --- a/plugins/scaffolder-backend-module-gitea/README.md +++ b/plugins/scaffolder-backend-module-gitea/README.md @@ -48,6 +48,8 @@ integrations: **NOTE**: As backstage will issue HTTPS/TLS requests to the gitea instance, it is needed to configure `gitea` with a valid certificate or at least with a self-signed certificate `gitea cert --host localhost -ca`. Don't forget to set the env var `NODE_EXTRA_CA_CERTS` to point to the CA pem file before to launch backstage ! +**WARNING**: Please pass the branch name part of the `catalogInfoPath` for the action `register` till we will fix this issue (e.g `main/catalog-info.yaml`) ! + When done, you can use the action in your template: ```yaml @@ -147,7 +149,7 @@ spec: action: catalog:register input: repoContentsUrl: ${{ steps['publish'].output.repoContentsUrl }} - catalogInfoPath: '/catalog-info.yaml' + catalogInfoPath: 'main/catalog-info.yaml' output: links: diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index 50b215f7d8..76ddb189a6 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -302,6 +302,16 @@ export function createPublishGiteaAction(options: { gitAuthorInfo, }); + /* + TODO: This code is commented till it will be fixed. + When we use the code hereafter, we got the following error: + "Unable to read url, Error: Unknown encoding: undefined\n at DefaultLocationService.processEntities" + as commented here: Still getting the error: https://github.com/backstage/backstage/pull/21890#issuecomment-1876733870 + + Such an issue do not exist using sleep 3s. + + WARNING: To allow to register within the catalog the new project, it is also needed to pass within the catalogInfoPath the branch name (e.g: main/catalog-info.yaml) + // Check if the repo is available let response: Response; response = await checkGiteaOrgRepo(integrationConfig.config, { @@ -317,6 +327,8 @@ export function createPublishGiteaAction(options: { defaultBranch, }); } + */ + await sleep(3000); const repoContentsUrl = `${integrationConfig.config.baseUrl}/${owner}/${repo}/+/refs/${defaultBranch}`; ctx.output('remoteUrl', remoteUrl); From 82ae17b19c8764ee6691f55b13258d0f59d07803 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 4 Jan 2024 18:27:24 +0100 Subject: [PATCH 53/82] Use the proper repoContentsUrl to access gitea repo and enhance the test case Signed-off-by: cmoulliard --- .../src/actions/gitea.test.ts | 5 +++++ plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts index 5486b5b69f..8936c34690 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts @@ -137,6 +137,11 @@ describe('publish:gitea', () => { name: undefined, }, }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gitea.com/org1/repo/src/branch/main', + ); }); afterEach(() => { diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index 76ddb189a6..b8ab703460 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -330,7 +330,7 @@ export function createPublishGiteaAction(options: { */ await sleep(3000); - const repoContentsUrl = `${integrationConfig.config.baseUrl}/${owner}/${repo}/+/refs/${defaultBranch}`; + const repoContentsUrl = `${integrationConfig.config.baseUrl}/${owner}/${repo}/src/branch/${defaultBranch}`; ctx.output('remoteUrl', remoteUrl); ctx.output('commitHash', commitResult?.commitHash); ctx.output('repoContentsUrl', repoContentsUrl); From a72521bae8a6991c4c2ddcd25aeba1bfff415512 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 4 Jan 2024 19:03:31 +0100 Subject: [PATCH 54/82] Adding a new test case covering the url we are looking for when we register a new entry to the catalog using the action. Removing the gerrit stuff Signed-off-by: cmoulliard --- packages/integration/src/gitea/core.test.ts | 36 +++++++++++---------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/packages/integration/src/gitea/core.test.ts b/packages/integration/src/gitea/core.test.ts index fe6381d52e..ba41fa4761 100644 --- a/packages/integration/src/gitea/core.test.ts +++ b/packages/integration/src/gitea/core.test.ts @@ -30,6 +30,22 @@ describe('gitea core', () => { const worker = setupServer(); setupRequestMockHandlers(worker); + describe('getGiteaFileCatalogInfoCntentsUrl', () => { + it('can create an url from arguments', () => { + const config: GiteaIntegrationConfig = { + host: 'gitea.com', + }; + expect( + getGiteaFileContentsUrl( + config, + 'https://gitea.com/org1/repo1/src/branch/main/catalog-info.yaml', + ), + ).toEqual( + 'https://gitea.com/api/v1/repos/org1/repo1/contents/catalog-info.yaml?ref=main', + ); + }); + }); + describe('getGiteaFileContentsUrl', () => { it('can create an url from arguments', () => { const config: GiteaIntegrationConfig = { @@ -94,29 +110,15 @@ describe('gitea core', () => { }); }); - describe('getGerritRequestOptions', () => { - it('adds token header when only a password is specified', () => { - const authRequest: GiteaIntegrationConfig = { - host: 'gerrit.com', - password: 'P', - }; - const anonymousRequest: GiteaIntegrationConfig = { - host: 'gerrit.com', - }; - expect( - (getGiteaRequestOptions(authRequest).headers as any).Authorization, - ).toEqual('token P'); - expect(getGiteaRequestOptions(anonymousRequest).headers).toBeUndefined(); - }); - + describe('getGiteaRequestOptions', () => { it('adds basic auth when username and password are specified', () => { const authRequest: GiteaIntegrationConfig = { - host: 'gerrit.com', + host: 'gitea.com', username: 'username', password: 'P', }; - const basicAuthentication = `basic ${Buffer.from( + const basicAuthentication = `Basic ${Buffer.from( `${authRequest.username}:${authRequest.password}`, ).toString('base64')}`; From 2b2fdccaa68bdb98826bce846d272574a35e0510 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 4 Jan 2024 19:15:53 +0100 Subject: [PATCH 55/82] Fixing the issue about the branch name not included to the url converted. Wrong: "https://localhost:3333/api/v1/repos/org1/repo1/contents/?ref=catalog-info.yaml" and good: "https://localhost:3333/api/v1/repos/org1/repo1/contents/catalog-info.yaml?ref=maincatalog-info.yaml" Signed-off-by: cmoulliard --- plugins/scaffolder-backend-module-gitea/README.md | 2 -- plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/README.md b/plugins/scaffolder-backend-module-gitea/README.md index 6b42eca9d0..4a710a400c 100644 --- a/plugins/scaffolder-backend-module-gitea/README.md +++ b/plugins/scaffolder-backend-module-gitea/README.md @@ -48,8 +48,6 @@ integrations: **NOTE**: As backstage will issue HTTPS/TLS requests to the gitea instance, it is needed to configure `gitea` with a valid certificate or at least with a self-signed certificate `gitea cert --host localhost -ca`. Don't forget to set the env var `NODE_EXTRA_CA_CERTS` to point to the CA pem file before to launch backstage ! -**WARNING**: Please pass the branch name part of the `catalogInfoPath` for the action `register` till we will fix this issue (e.g `main/catalog-info.yaml`) ! - When done, you can use the action in your template: ```yaml diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index b8ab703460..7905f42e4a 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -31,6 +31,7 @@ import { examples } from './gitea.examples'; import fetch, { RequestInit, Response } from 'node-fetch'; import crypto from 'crypto'; +/* NOT USED. See TODO hereafter const checkGiteaOrgRepo = async ( config: GiteaIntegrationConfig, options: { @@ -61,6 +62,8 @@ const checkGiteaOrgRepo = async ( } return response; }; +*/ + const checkGiteaOrg = async ( config: GiteaIntegrationConfig, options: { @@ -330,7 +333,7 @@ export function createPublishGiteaAction(options: { */ await sleep(3000); - const repoContentsUrl = `${integrationConfig.config.baseUrl}/${owner}/${repo}/src/branch/${defaultBranch}`; + const repoContentsUrl = `${integrationConfig.config.baseUrl}/${owner}/${repo}/src/branch/${defaultBranch}/`; ctx.output('remoteUrl', remoteUrl); ctx.output('commitHash', commitResult?.commitHash); ctx.output('repoContentsUrl', repoContentsUrl); From 73295aa0df6c4b4f4ceef997b42ce502a1237cb6 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 4 Jan 2024 19:48:35 +0100 Subject: [PATCH 56/82] Change the request to test if the URL is reposning after the repo has been created. We dont get anymore Error: Unknown encoding: undefined during register action step Signed-off-by: cmoulliard --- .../src/actions/gitea.ts | 29 ++++--------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index 7905f42e4a..412d437a7a 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -31,8 +31,8 @@ import { examples } from './gitea.examples'; import fetch, { RequestInit, Response } from 'node-fetch'; import crypto from 'crypto'; -/* NOT USED. See TODO hereafter -const checkGiteaOrgRepo = async ( +/* NOT USED. See TODO hereafter */ +const checkGiteaContentUrl = async ( config: GiteaIntegrationConfig, options: { owner?: string; @@ -44,15 +44,11 @@ const checkGiteaOrgRepo = async ( let response: Response; const getOptions: RequestInit = { method: 'GET', - headers: { - ...getGiteaRequestOptions(config).headers, - 'Content-Type': 'application/json', - }, }; try { response = await fetch( - `${config.baseUrl}/api/v1/repos/${owner}/${repo}/contents?ref=${defaultBranch}`, + `${config.baseUrl}/${owner}/${repo}/src/branch/${defaultBranch}`, getOptions, ); } catch (e) { @@ -62,7 +58,6 @@ const checkGiteaOrgRepo = async ( } return response; }; -*/ const checkGiteaOrg = async ( config: GiteaIntegrationConfig, @@ -305,33 +300,21 @@ export function createPublishGiteaAction(options: { gitAuthorInfo, }); - /* - TODO: This code is commented till it will be fixed. - When we use the code hereafter, we got the following error: - "Unable to read url, Error: Unknown encoding: undefined\n at DefaultLocationService.processEntities" - as commented here: Still getting the error: https://github.com/backstage/backstage/pull/21890#issuecomment-1876733870 - - Such an issue do not exist using sleep 3s. - - WARNING: To allow to register within the catalog the new project, it is also needed to pass within the catalogInfoPath the branch name (e.g: main/catalog-info.yaml) - - // Check if the repo is available + // Check if the gitea repo URL is available before to exit let response: Response; - response = await checkGiteaOrgRepo(integrationConfig.config, { + response = await checkGiteaContentUrl(integrationConfig.config, { owner, repo, defaultBranch, }); while (response.status !== 200) { await sleep(1000); - response = await checkGiteaOrgRepo(integrationConfig.config, { + response = await checkGiteaContentUrl(integrationConfig.config, { owner, repo, defaultBranch, }); } - */ - await sleep(3000); const repoContentsUrl = `${integrationConfig.config.baseUrl}/${owner}/${repo}/src/branch/${defaultBranch}/`; ctx.output('remoteUrl', remoteUrl); From a6b552b40733bcbcec3bade18b57481620028568 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Fri, 5 Jan 2024 16:31:18 +0100 Subject: [PATCH 57/82] Adding a new rest.get to allow gitea to check if the URL of the repo exists Signed-off-by: cmoulliard --- .../src/actions/gitea.test.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts index 8936c34690..0ab2fd507b 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts @@ -100,6 +100,16 @@ describe('publish:gitea', () => { }), ); }), + rest.get( + 'https://gitea.com/org1/repo/src/branch/main', + (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }, + ), rest.post('https://gitea.com/api/v1/orgs/org1/repos', (req, res, ctx) => { // Basic auth must match the user and password defined part of the config expect(req.headers.get('Authorization')).toBe( @@ -140,7 +150,7 @@ describe('publish:gitea', () => { expect(mockContext.output).toHaveBeenCalledWith( 'repoContentsUrl', - 'https://gitea.com/org1/repo/src/branch/main', + 'https://gitea.com/org1/repo/src/branch/main/', ); }); From 317d62675d3ee8c7cfb4c61bccb79a66021a6c66 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Fri, 5 Jan 2024 17:04:59 +0100 Subject: [PATCH 58/82] Fixing errors reported by documentation quality check github job Signed-off-by: cmoulliard --- .changeset/metal-clocks-suffer.md | 2 +- plugins/scaffolder-backend-module-gitea/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/metal-clocks-suffer.md b/.changeset/metal-clocks-suffer.md index f94deb380c..648276d4dd 100644 --- a/.changeset/metal-clocks-suffer.md +++ b/.changeset/metal-clocks-suffer.md @@ -5,4 +5,4 @@ '@backstage/integration': patch --- -Added support to create a git repository and publish a scaffolded project using a new action "publish:gitea" for gitea. The action currently supports to create a gitea org's repository - https://gitea.com/api/swagger#/organization/createOrgRepo +Added support to create a git repository and publish a scaffolded project using a new action "publish:gitea" for gitea. The action currently supports to create a gitea repository owned by an organization. See: https://gitea.com/api/swagger#/organization/createOrgRepo diff --git a/plugins/scaffolder-backend-module-gitea/README.md b/plugins/scaffolder-backend-module-gitea/README.md index 4a710a400c..8f9d39f4dc 100644 --- a/plugins/scaffolder-backend-module-gitea/README.md +++ b/plugins/scaffolder-backend-module-gitea/README.md @@ -46,7 +46,7 @@ integrations: ``` **NOTE**: As backstage will issue HTTPS/TLS requests to the gitea instance, it is needed to configure `gitea` with a valid certificate or at least with a -self-signed certificate `gitea cert --host localhost -ca`. Don't forget to set the env var `NODE_EXTRA_CA_CERTS` to point to the CA pem file before to launch backstage ! +self-signed certificate `gitea cert --host localhost -ca`. Don't forget to set the env var `NODE_EXTRA_CA_CERTS` to point to the CA file before to launch backstage ! When done, you can use the action in your template: From e300ddacd903fb35713c614c50f74cfced627298 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 10 Jan 2024 10:28:04 +0100 Subject: [PATCH 59/82] Revert change Token to token as gitea checks token word only. "https://docs.gitea.com/next/development/api-usage\#authentication" Signed-off-by: cmoulliard --- packages/integration/src/gitea/core.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/integration/src/gitea/core.ts b/packages/integration/src/gitea/core.ts index f188613d2a..6d11a4ffde 100644 --- a/packages/integration/src/gitea/core.ts +++ b/packages/integration/src/gitea/core.ts @@ -124,7 +124,7 @@ export function getGiteaRequestOptions(config: GiteaIntegrationConfig): { `${username}:${password}`, ).toString('base64')}`; } else { - headers.Authorization = `Token ${password}`; + headers.Authorization = `token ${password}`; } return { From 0c211065dd715ca2fe0a1d0b3584e241bb3a8b04 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 10 Jan 2024 10:40:39 +0100 Subject: [PATCH 60/82] Better documented the changes of this PR part of the changeset file Signed-off-by: cmoulliard --- .changeset/metal-clocks-suffer.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.changeset/metal-clocks-suffer.md b/.changeset/metal-clocks-suffer.md index 648276d4dd..4cba0ba35b 100644 --- a/.changeset/metal-clocks-suffer.md +++ b/.changeset/metal-clocks-suffer.md @@ -5,4 +5,10 @@ '@backstage/integration': patch --- -Added support to create a git repository and publish a scaffolded project using a new action "publish:gitea" for gitea. The action currently supports to create a gitea repository owned by an organization. See: https://gitea.com/api/swagger#/organization/createOrgRepo +Created a gitea module for the scaffolder. This module provides a new action "publish:gitea" able to create a gitea repository owned by an organization. See: https://gitea.com/api/swagger#/organization/createOrgRepo + +Fixed the gitea authorization headers (used by the integration module) to lower case the words: token and basic + +Added a new test case to the integration module to verify the url of the gitea repository created by the getGiteaFileContentsUrl function. + +Verifying if the basicURL processed by the readGiteaConfig function is valid From 71c68535ae3605cf4083ef264e7ce8440743cea4 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 10 Jan 2024 10:41:38 +0100 Subject: [PATCH 61/82] Revert Basic to basic as the word checked by gitea api is basic Signed-off-by: cmoulliard --- packages/integration/src/gitea/core.test.ts | 2 +- packages/integration/src/gitea/core.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/integration/src/gitea/core.test.ts b/packages/integration/src/gitea/core.test.ts index ba41fa4761..ac29c469b6 100644 --- a/packages/integration/src/gitea/core.test.ts +++ b/packages/integration/src/gitea/core.test.ts @@ -118,7 +118,7 @@ describe('gitea core', () => { password: 'P', }; - const basicAuthentication = `Basic ${Buffer.from( + const basicAuthentication = `basic ${Buffer.from( `${authRequest.username}:${authRequest.password}`, ).toString('base64')}`; diff --git a/packages/integration/src/gitea/core.ts b/packages/integration/src/gitea/core.ts index 6d11a4ffde..95caa24c06 100644 --- a/packages/integration/src/gitea/core.ts +++ b/packages/integration/src/gitea/core.ts @@ -120,7 +120,7 @@ export function getGiteaRequestOptions(config: GiteaIntegrationConfig): { } if (username) { - headers.Authorization = `Basic ${Buffer.from( + headers.Authorization = `basic ${Buffer.from( `${username}:${password}`, ).toString('base64')}`; } else { From a755bf4bf758486236e0e7db1bc7ce984c431061 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 10 Jan 2024 10:51:31 +0100 Subject: [PATCH 62/82] Remove the non needed code block as createBuiltinActions.ts is a new function exported from latest backstage distribution and gitea will be included when this PR will be merged Signed-off-by: cmoulliard --- .../scaffolder-backend-module-gitea/README.md | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/README.md b/plugins/scaffolder-backend-module-gitea/README.md index 8f9d39f4dc..c35138a34c 100644 --- a/plugins/scaffolder-backend-module-gitea/README.md +++ b/plugins/scaffolder-backend-module-gitea/README.md @@ -14,23 +14,6 @@ yarn add --cwd packages/backend Configure the action (if not yet done): (you can check the [docs](https://backstage.io/docs/features/software-templates/writing-custom-actions#registering-custom-actions) to see all options): -```typescript -// plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts - -export const createBuiltinActions = ( -... - const actions = [ - ... - createPublishGiteaAction({ - integrations, - config, - }), - ... - ]; - return actions as TemplateAction[]; -}; -``` - Before to create a template, include to your `app-config.yaml` file the gitea host and credentials under the `integrations:` section From b39db7dc78060ab6f509858e6954cb68b6dc9ab1 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 10 Jan 2024 10:52:37 +0100 Subject: [PATCH 63/82] Change to launch backstage with launching backstage Signed-off-by: cmoulliard --- plugins/scaffolder-backend-module-gitea/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend-module-gitea/README.md b/plugins/scaffolder-backend-module-gitea/README.md index c35138a34c..fe42b2fbaf 100644 --- a/plugins/scaffolder-backend-module-gitea/README.md +++ b/plugins/scaffolder-backend-module-gitea/README.md @@ -29,7 +29,7 @@ integrations: ``` **NOTE**: As backstage will issue HTTPS/TLS requests to the gitea instance, it is needed to configure `gitea` with a valid certificate or at least with a -self-signed certificate `gitea cert --host localhost -ca`. Don't forget to set the env var `NODE_EXTRA_CA_CERTS` to point to the CA file before to launch backstage ! +self-signed certificate `gitea cert --host localhost -ca`. Don't forget to set the env var `NODE_EXTRA_CA_CERTS` to point to the CA file before launching backstage ! When done, you can use the action in your template: From 6f145d5097cc02b80977632342327c17cd9a47a7 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 10 Jan 2024 10:59:21 +0100 Subject: [PATCH 64/82] Removed non needed text from the template example and improved the changes todo in a template Signed-off-by: cmoulliard --- .../scaffolder-backend-module-gitea/README.md | 50 +++---------------- 1 file changed, 8 insertions(+), 42 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/README.md b/plugins/scaffolder-backend-module-gitea/README.md index fe42b2fbaf..f13602f2d8 100644 --- a/plugins/scaffolder-backend-module-gitea/README.md +++ b/plugins/scaffolder-backend-module-gitea/README.md @@ -31,7 +31,10 @@ integrations: **NOTE**: As backstage will issue HTTPS/TLS requests to the gitea instance, it is needed to configure `gitea` with a valid certificate or at least with a self-signed certificate `gitea cert --host localhost -ca`. Don't forget to set the env var `NODE_EXTRA_CA_CERTS` to point to the CA file before launching backstage ! -When done, you can use the action in your template: +When done, you can create a template which: + +- Declare the `RepoUrlPicker` within the `spec/parameters` section to select the gitea hosts +- Include a step able to publish by example the newly generated project using the action `action: publish:gitea` ```yaml apiVersion: scaffolder.backstage.io/v1beta3 @@ -47,43 +50,7 @@ spec: owner: quarkus type: service parameters: - - title: Provide Information for Application - required: - - component_id - - owner - - java_package_name - properties: - component_id: - title: Name - type: string - description: Unique name of the component - default: my-quarkus-app - ui:field: EntityNamePicker - group_id: - title: Group Id - type: string - default: io.quarkus - description: Maven Group Id - artifact_id: - title: Artifact Id - type: string - default: quarkus-app - description: Maven Artifact Id - java_package_name: - title: Java Package Name - default: io.quarkus.demo - type: string - description: Name for the java package. eg (io.quarkus.blah) - owner: - title: Owner - type: string - description: IdP owner of the component - ui:field: OwnerPicker - ui:options: - allowedKinds: - - Group - - - title: Application git repository Information + - title: Git repository Information required: - repoUrl properties: @@ -93,8 +60,8 @@ spec: ui:field: RepoUrlPicker ui:options: allowedHosts: - - localhost:3333 - gitea.: + - localhost: steps: - id: template @@ -112,8 +79,7 @@ spec: artifact_id: ${{ parameters.artifact_id }} java_package_name: ${{ parameters.java_package_name }} owner: ${{ parameters.owner }} - destination: ${{ (parameters.repoUrl | parseRepoUrl).owner }}/${{ (parameters.repoUrl | parseRepoUrl).repo }} - quay_destination: ${{ parameters.image_organization }}/${{ parameters.component_id }} + destination: ${{ (parameters.repoUrl | parseRepoUrl).owner }}/${{ (parameters.repoUrl | parseRepoUrl).repo } port: 8080 - id: publish @@ -141,4 +107,4 @@ spec: entityRef: ${{ steps.register.output.entityRef }} ``` -Enjoy ;-) +Access the newly gitea repository created using the `repoContentsUrl` ;-) From 25c3850edf06a1fb96139448d88ec3948bc95d40 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 10 Jan 2024 11:09:16 +0100 Subject: [PATCH 65/82] Removing import of node-fetch to use the node built in fetch function directly Signed-off-by: cmoulliard --- .../scaffolder-backend-module-gitea/src/actions/gitea.test.ts | 2 +- plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts index 0ab2fd507b..5e1e94b1b4 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts @@ -113,7 +113,7 @@ describe('publish:gitea', () => { rest.post('https://gitea.com/api/v1/orgs/org1/repos', (req, res, ctx) => { // Basic auth must match the user and password defined part of the config expect(req.headers.get('Authorization')).toBe( - 'Basic Z2l0ZWFfdXNlcjpnaXRlYV9wYXNzd29yZA==', + 'basic Z2l0ZWFfdXNlcjpnaXRlYV9wYXNzd29yZA==', ); expect(req.body).toEqual({ name: 'repo', diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index 412d437a7a..c022bf4d08 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -28,10 +28,8 @@ import { parseRepoUrl, } from '@backstage/plugin-scaffolder-node'; import { examples } from './gitea.examples'; -import fetch, { RequestInit, Response } from 'node-fetch'; import crypto from 'crypto'; -/* NOT USED. See TODO hereafter */ const checkGiteaContentUrl = async ( config: GiteaIntegrationConfig, options: { From 107050672c69def8fbfe4131041d9514f76da6e3 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 10 Jan 2024 12:19:20 +0100 Subject: [PATCH 66/82] Add a function to test if while don't exceed 20s and test if signal is aborted Signed-off-by: cmoulliard --- .../src/actions/gitea.ts | 86 +++++++++++++++---- 1 file changed, 70 insertions(+), 16 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index c022bf4d08..d38802d76e 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -18,10 +18,13 @@ import { InputError } from '@backstage/errors'; import { Config } from '@backstage/config'; import { getGiteaRequestOptions, + GiteaIntegration, GiteaIntegrationConfig, ScmIntegrationRegistry, + ScmIntegrationsGroup, } from '@backstage/integration'; import { + ActionContext, createTemplateAction, getRepoSourceDirectory, initRepoAndPush, @@ -149,6 +152,54 @@ const generateCommitMessage = ( return msg; }; +/** + * Checks if the provided function can be executed within a specific period of time limit. + * @param fn + * @param timeLimit + */ +function checkDurationLimit(fn: () => void, timeLimit: number): boolean { + const startTime = process.hrtime(); + + // Call the function + fn(); + + const endTime = process.hrtime(startTime); + const durationInMs = endTime[0] * 1000 + endTime[1] / 1e6; + + // Check if the duration exceeds the time limit + return durationInMs <= timeLimit; +} + +export async function checkAvailabilityGiteaRepository( + integrationConfig: GiteaIntegrationConfig, + options: { + owner?: string; + repo: string; + defaultBranch: string; + ctx: ActionContext; + }, +) { + const { owner, repo, defaultBranch, ctx } = options; + const sleep = (ms: number | undefined) => new Promise(r => setTimeout(r, ms)); + let response: Response; + + response = await checkGiteaContentUrl(integrationConfig, { + owner, + repo, + defaultBranch, + }); + + while (response.status !== 200) { + if (ctx.signal?.aborted) return; + await sleep(1000); + response = await checkGiteaContentUrl(integrationConfig, { + owner, + repo, + defaultBranch, + }); + } +} + /** * Creates a new action that initializes a git repository using the content of the workspace. * and publishes it to a Gitea instance. @@ -242,9 +293,6 @@ export function createPublishGiteaAction(options: { sourcePath, } = ctx.input; - const sleep = (ms: number | undefined) => - new Promise(r => setTimeout(r, ms)); - const { repo, host, owner } = parseRepoUrl(repoUrl, integrations); const integrationConfig = integrations.gitea.byHost(host); @@ -299,19 +347,20 @@ export function createPublishGiteaAction(options: { }); // Check if the gitea repo URL is available before to exit - let response: Response; - response = await checkGiteaContentUrl(integrationConfig.config, { - owner, - repo, - defaultBranch, - }); - while (response.status !== 200) { - await sleep(1000); - response = await checkGiteaContentUrl(integrationConfig.config, { - owner, - repo, - defaultBranch, - }); + const operationTimeLimit = 20000; // 20 seconds + const checkDuration = checkDurationLimit( + () => + checkAvailabilityGiteaRepository(integrationConfig.config, { + owner, + repo, + defaultBranch, + ctx, + }), + operationTimeLimit, + ); + + if (!checkDuration) { + console.log('Operation exceeded the time limit.'); } const repoContentsUrl = `${integrationConfig.config.baseUrl}/${owner}/${repo}/src/branch/${defaultBranch}/`; @@ -321,3 +370,8 @@ export function createPublishGiteaAction(options: { }, }); } + +async function dummySleep() { + const sleep = (ms: number | undefined) => new Promise(r => setTimeout(r, ms)); + await sleep(10000); +} From 48ecd88b134b3c79d70ee4ee6cad13b0a755cce2 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 10 Jan 2024 12:22:24 +0100 Subject: [PATCH 67/82] Declaring const { username, password } earlier within the file Signed-off-by: cmoulliard --- .../src/actions/gitea.ts | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index d38802d76e..35af81ce91 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -301,11 +301,9 @@ export function createPublishGiteaAction(options: { `No matching integration configuration for host ${host}, please check your integrations config`, ); } + const { username, password } = integrationConfig.config; - if ( - !integrationConfig.config.username || - !integrationConfig.config.password - ) { + if (!username || !password) { throw new Error( 'Credentials for Gitea integration required for this action.', ); @@ -323,8 +321,8 @@ export function createPublishGiteaAction(options: { }); const auth = { - username: integrationConfig.config.username!, - password: integrationConfig.config.password!, + username: username, + password: password, }; const gitAuthorInfo = { name: gitAuthorName @@ -370,8 +368,3 @@ export function createPublishGiteaAction(options: { }, }); } - -async function dummySleep() { - const sleep = (ms: number | undefined) => new Promise(r => setTimeout(r, ms)); - await sleep(10000); -} From 8c9b90bb3e7c38ca1be5b5288921800473355dfe Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 10 Jan 2024 12:24:49 +0100 Subject: [PATCH 68/82] Declaring the variables username, password earlier and change the message to pass the host for the missing credentials Signed-off-by: cmoulliard --- plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index 35af81ce91..17fbf7ab0b 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -304,9 +304,7 @@ export function createPublishGiteaAction(options: { const { username, password } = integrationConfig.config; if (!username || !password) { - throw new Error( - 'Credentials for Gitea integration required for this action.', - ); + throw new Error('Credentials for the gitea ${host} required.'); } // check if the org exists within the gitea server From 842b9c00b79cb6b28ea689e1aed83b4caec662e0 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 10 Jan 2024 12:38:13 +0100 Subject: [PATCH 69/82] Removing ScmIntegrationsGroup & GiteaIntegration from import as non used Signed-off-by: cmoulliard --- plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index 17fbf7ab0b..a2845a74c6 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -18,10 +18,8 @@ import { InputError } from '@backstage/errors'; import { Config } from '@backstage/config'; import { getGiteaRequestOptions, - GiteaIntegration, GiteaIntegrationConfig, ScmIntegrationRegistry, - ScmIntegrationsGroup, } from '@backstage/integration'; import { ActionContext, From 4ed5ffebdfb0670afb61e4949e8f28b0ca290c2c Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Tue, 16 Jan 2024 14:27:14 +0100 Subject: [PATCH 70/82] Removing the export prefix for the function: checkAvailabilityGiteaRepository as it used internally Signed-off-by: cmoulliard --- plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index a2845a74c6..bd592cce4b 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -168,7 +168,7 @@ function checkDurationLimit(fn: () => void, timeLimit: number): boolean { return durationInMs <= timeLimit; } -export async function checkAvailabilityGiteaRepository( +async function checkAvailabilityGiteaRepository( integrationConfig: GiteaIntegrationConfig, options: { owner?: string; From 95b4910cf87076a5461a9ab64fd5f0d094e96b11 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 18 Jan 2024 16:12:30 +0100 Subject: [PATCH 71/82] Adding to tsc --skipLibCheck false --incremental false Signed-off-by: cmoulliard --- .github/workflows/deploy_packages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index c91fec948e..40351cba78 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -161,7 +161,7 @@ jobs: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - name: build type declarations - run: yarn tsc:full + run: yarn tsc --skipLibCheck false --incremental false - name: build packages run: yarn backstage-cli repo build From d7b0c272c3f2535fccfbd00b89bd2bf2b83b2c66 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 18 Jan 2024 16:23:29 +0100 Subject: [PATCH 72/82] Revert "Adding to tsc --skipLibCheck false --incremental false" This reverts commit 11862cc739b2e2651a10d88169522e6fa16854fd. Signed-off-by: cmoulliard --- .github/workflows/deploy_packages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index 40351cba78..c91fec948e 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -161,7 +161,7 @@ jobs: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - name: build type declarations - run: yarn tsc --skipLibCheck false --incremental false + run: yarn tsc:full - name: build packages run: yarn backstage-cli repo build From 9b0bf20dba51b75029916978de74e014416ce7af Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Tue, 30 Jan 2024 16:33:40 +0100 Subject: [PATCH 73/82] Removed non relevant information from changeset and splitting changes into 2 changeset files Signed-off-by: cmoulliard --- .changeset/metal-clocks-suffer.md | 8 -------- .changeset/thick-pillows-punch.md | 5 +++++ 2 files changed, 5 insertions(+), 8 deletions(-) create mode 100644 .changeset/thick-pillows-punch.md diff --git a/.changeset/metal-clocks-suffer.md b/.changeset/metal-clocks-suffer.md index 4cba0ba35b..c459be9fa5 100644 --- a/.changeset/metal-clocks-suffer.md +++ b/.changeset/metal-clocks-suffer.md @@ -1,14 +1,6 @@ --- '@backstage/plugin-scaffolder-backend-module-gitea': minor '@backstage/plugin-scaffolder-backend': minor -'@backstage/plugin-scaffolder-node': minor -'@backstage/integration': patch --- Created a gitea module for the scaffolder. This module provides a new action "publish:gitea" able to create a gitea repository owned by an organization. See: https://gitea.com/api/swagger#/organization/createOrgRepo - -Fixed the gitea authorization headers (used by the integration module) to lower case the words: token and basic - -Added a new test case to the integration module to verify the url of the gitea repository created by the getGiteaFileContentsUrl function. - -Verifying if the basicURL processed by the readGiteaConfig function is valid diff --git a/.changeset/thick-pillows-punch.md b/.changeset/thick-pillows-punch.md new file mode 100644 index 0000000000..def589d3f8 --- /dev/null +++ b/.changeset/thick-pillows-punch.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-node': patch +--- + +Add gitea as new type to be used from integrations configuration From b4748b36eb875218ad7340ef19aa1f50bd83841b Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Tue, 30 Jan 2024 17:40:06 +0100 Subject: [PATCH 74/82] Refactoring the code to include the maxDuration within the function checking if gitea repository is available Signed-off-by: cmoulliard --- .../src/actions/gitea.ts | 60 +++++++------------ 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index bd592cce4b..e7f62f51da 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -150,25 +150,8 @@ const generateCommitMessage = ( return msg; }; -/** - * Checks if the provided function can be executed within a specific period of time limit. - * @param fn - * @param timeLimit - */ -function checkDurationLimit(fn: () => void, timeLimit: number): boolean { - const startTime = process.hrtime(); - - // Call the function - fn(); - - const endTime = process.hrtime(startTime); - const durationInMs = endTime[0] * 1000 + endTime[1] / 1e6; - - // Check if the duration exceeds the time limit - return durationInMs <= timeLimit; -} - async function checkAvailabilityGiteaRepository( + maxDuration: number, integrationConfig: GiteaIntegrationConfig, options: { owner?: string; @@ -177,24 +160,25 @@ async function checkAvailabilityGiteaRepository( ctx: ActionContext; }, ) { + const startTimestamp = Date.now(); + const { owner, repo, defaultBranch, ctx } = options; const sleep = (ms: number | undefined) => new Promise(r => setTimeout(r, ms)); let response: Response; - response = await checkGiteaContentUrl(integrationConfig, { - owner, - repo, - defaultBranch, - }); - - while (response.status !== 200) { + while (Date.now() - startTimestamp < maxDuration) { if (ctx.signal?.aborted) return; - await sleep(1000); + response = await checkGiteaContentUrl(integrationConfig, { owner, repo, defaultBranch, }); + + if (response.status !== 200) { + // Repository is not yet available/accessible ... + await sleep(1000); + } } } @@ -341,22 +325,18 @@ export function createPublishGiteaAction(options: { }); // Check if the gitea repo URL is available before to exit - const operationTimeLimit = 20000; // 20 seconds - const checkDuration = checkDurationLimit( - () => - checkAvailabilityGiteaRepository(integrationConfig.config, { - owner, - repo, - defaultBranch, - ctx, - }), - operationTimeLimit, + const maxDuration = 20000; // 20 seconds + await checkAvailabilityGiteaRepository( + maxDuration, + integrationConfig.config, + { + owner, + repo, + defaultBranch, + ctx, + }, ); - if (!checkDuration) { - console.log('Operation exceeded the time limit.'); - } - const repoContentsUrl = `${integrationConfig.config.baseUrl}/${owner}/${repo}/src/branch/${defaultBranch}/`; ctx.output('remoteUrl', remoteUrl); ctx.output('commitHash', commitResult?.commitHash); From 2d0e7cdc69982cc935778519da106d243bea693b Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 1 Feb 2024 11:40:47 +0100 Subject: [PATCH 75/82] Add new changeset file to document what changed for @backstage/integration Signed-off-by: cmoulliard --- .changeset/shiny-jeans-begin.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/shiny-jeans-begin.md diff --git a/.changeset/shiny-jeans-begin.md b/.changeset/shiny-jeans-begin.md new file mode 100644 index 0000000000..d542747b34 --- /dev/null +++ b/.changeset/shiny-jeans-begin.md @@ -0,0 +1,5 @@ +--- +'@backstage/integration': patch +--- + +Validate if the `baseUrl` is a valid URL From 06c1fce211ffd767298209407062736a3bf352b5 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 14 Feb 2024 19:05:54 +0100 Subject: [PATCH 76/82] Migrate the module to new Backend System Signed-off-by: cmoulliard --- .../api-report-alpha.md | 13 +++++ .../package.json | 17 ++++++- .../src/alpha.ts | 16 +++++++ .../src/module.ts | 48 +++++++++++++++++++ yarn.lock | 2 +- 5 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 plugins/scaffolder-backend-module-gitea/api-report-alpha.md create mode 100644 plugins/scaffolder-backend-module-gitea/src/alpha.ts create mode 100644 plugins/scaffolder-backend-module-gitea/src/module.ts diff --git a/plugins/scaffolder-backend-module-gitea/api-report-alpha.md b/plugins/scaffolder-backend-module-gitea/api-report-alpha.md new file mode 100644 index 0000000000..8cd41a271c --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/api-report-alpha.md @@ -0,0 +1,13 @@ +## API Report File for "@backstage/plugin-scaffolder-backend-module-gitea" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @public +const giteaModule: () => BackendFeature; +export default giteaModule; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/scaffolder-backend-module-gitea/package.json b/plugins/scaffolder-backend-module-gitea/package.json index c9e9a4e07d..13e57c9337 100644 --- a/plugins/scaffolder-backend-module-gitea/package.json +++ b/plugins/scaffolder-backend-module-gitea/package.json @@ -13,6 +13,21 @@ "backstage": { "role": "backend-plugin-module" }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } + }, "scripts": { "start": "backstage-cli package start", "build": "backstage-cli package build", @@ -23,10 +38,10 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { + "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/integration": "workspace:^", - "@backstage/plugin-scaffolder-backend": "workspace:^", "@backstage/plugin-scaffolder-node": "workspace:^", "node-fetch": "^2.6.7", "yaml": "^2.0.0" diff --git a/plugins/scaffolder-backend-module-gitea/src/alpha.ts b/plugins/scaffolder-backend-module-gitea/src/alpha.ts new file mode 100644 index 0000000000..7c5ee49afa --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/src/alpha.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { giteaModule as default } from './module'; diff --git a/plugins/scaffolder-backend-module-gitea/src/module.ts b/plugins/scaffolder-backend-module-gitea/src/module.ts new file mode 100644 index 0000000000..658f240471 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/src/module.ts @@ -0,0 +1,48 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + createBackendModule, + coreServices, +} from '@backstage/backend-plugin-api'; +import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; +import { createPublishGiteaAction } from './actions'; +import { ScmIntegrations } from '@backstage/integration'; + +/** + * @public + * The Gitea Module for the Scaffolder Backend + */ +export const giteaModule = createBackendModule({ + pluginId: 'scaffolder', + moduleId: 'gitea', + register({ registerInit }) { + registerInit({ + deps: { + scaffolder: scaffolderActionsExtensionPoint, + config: coreServices.rootConfig, + }, + async init({ scaffolder, config }) { + const integrations = ScmIntegrations.fromConfig(config); + scaffolder.addActions( + createPublishGiteaAction({ + integrations, + config, + }), + ); + }, + }); + }, +}); diff --git a/yarn.lock b/yarn.lock index 64bc6fc64e..3291d13beb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8497,12 +8497,12 @@ __metadata: resolution: "@backstage/plugin-scaffolder-backend-module-gitea@workspace:plugins/scaffolder-backend-module-gitea" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" - "@backstage/plugin-scaffolder-backend": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" msw: ^1.0.0 node-fetch: ^2.6.7 From 446dba2323bcc09522521e655be887ed38d869b4 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 15 Feb 2024 16:36:07 +0100 Subject: [PATCH 77/82] Only export index.ts and not alpha.ts Signed-off-by: cmoulliard --- .../scaffolder-backend-module-gitea/package.json | 4 ---- .../scaffolder-backend-module-gitea/src/alpha.ts | 16 ---------------- .../scaffolder-backend-module-gitea/src/index.ts | 1 + 3 files changed, 1 insertion(+), 20 deletions(-) delete mode 100644 plugins/scaffolder-backend-module-gitea/src/alpha.ts diff --git a/plugins/scaffolder-backend-module-gitea/package.json b/plugins/scaffolder-backend-module-gitea/package.json index 13e57c9337..f2623cc58e 100644 --- a/plugins/scaffolder-backend-module-gitea/package.json +++ b/plugins/scaffolder-backend-module-gitea/package.json @@ -15,14 +15,10 @@ }, "exports": { ".": "./src/index.ts", - "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, "typesVersions": { "*": { - "alpha": [ - "src/alpha.ts" - ], "package.json": [ "package.json" ] diff --git a/plugins/scaffolder-backend-module-gitea/src/alpha.ts b/plugins/scaffolder-backend-module-gitea/src/alpha.ts deleted file mode 100644 index 7c5ee49afa..0000000000 --- a/plugins/scaffolder-backend-module-gitea/src/alpha.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { giteaModule as default } from './module'; diff --git a/plugins/scaffolder-backend-module-gitea/src/index.ts b/plugins/scaffolder-backend-module-gitea/src/index.ts index 026da0735a..0b68069178 100644 --- a/plugins/scaffolder-backend-module-gitea/src/index.ts +++ b/plugins/scaffolder-backend-module-gitea/src/index.ts @@ -21,3 +21,4 @@ */ export * from './actions'; +export { giteaModule as default } from './module'; From 905f4708312f292796378c69f212cd8b125a1096 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Thu, 15 Feb 2024 21:07:32 +0100 Subject: [PATCH 78/82] Remove files to be published Signed-off-by: cmoulliard --- plugins/scaffolder-backend-module-gitea/package.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/scaffolder-backend-module-gitea/package.json b/plugins/scaffolder-backend-module-gitea/package.json index f2623cc58e..101c629243 100644 --- a/plugins/scaffolder-backend-module-gitea/package.json +++ b/plugins/scaffolder-backend-module-gitea/package.json @@ -6,9 +6,7 @@ "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" }, "backstage": { "role": "backend-plugin-module" From 8db9fdaf29af2a059c9f70728bed531678d65840 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Fri, 16 Feb 2024 12:31:22 +0100 Subject: [PATCH 79/82] Add git repository to the package.json file of the module Signed-off-by: cmoulliard --- plugins/scaffolder-backend-module-gitea/package.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/scaffolder-backend-module-gitea/package.json b/plugins/scaffolder-backend-module-gitea/package.json index 101c629243..17f30b226b 100644 --- a/plugins/scaffolder-backend-module-gitea/package.json +++ b/plugins/scaffolder-backend-module-gitea/package.json @@ -8,6 +8,11 @@ "publishConfig": { "access": "public" }, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/scaffolder-backend-module-gitea" + }, "backstage": { "role": "backend-plugin-module" }, From 9eb7cacef753cebd7db62786d8a41d89e83df3c7 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Fri, 16 Feb 2024 13:49:40 +0100 Subject: [PATCH 80/82] Regenerated the API report Signed-off-by: cmoulliard --- .../api-report-alpha.md | 13 ------------- .../scaffolder-backend-module-gitea/api-report.md | 5 +++++ 2 files changed, 5 insertions(+), 13 deletions(-) delete mode 100644 plugins/scaffolder-backend-module-gitea/api-report-alpha.md diff --git a/plugins/scaffolder-backend-module-gitea/api-report-alpha.md b/plugins/scaffolder-backend-module-gitea/api-report-alpha.md deleted file mode 100644 index 8cd41a271c..0000000000 --- a/plugins/scaffolder-backend-module-gitea/api-report-alpha.md +++ /dev/null @@ -1,13 +0,0 @@ -## API Report File for "@backstage/plugin-scaffolder-backend-module-gitea" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; - -// @public -const giteaModule: () => BackendFeature; -export default giteaModule; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/scaffolder-backend-module-gitea/api-report.md b/plugins/scaffolder-backend-module-gitea/api-report.md index f83ae73fb7..373cc6258c 100644 --- a/plugins/scaffolder-backend-module-gitea/api-report.md +++ b/plugins/scaffolder-backend-module-gitea/api-report.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { JsonObject } from '@backstage/types'; import { ScmIntegrationRegistry } from '@backstage/integration'; @@ -24,4 +25,8 @@ export function createPublishGiteaAction(options: { }, JsonObject >; + +// @public +const giteaModule: () => BackendFeature; +export default giteaModule; ``` From 1cfcb469cd5d4237d333e0b5ddb3d642809c85a0 Mon Sep 17 00:00:00 2001 From: blam Date: Fri, 16 Feb 2024 17:28:03 +0100 Subject: [PATCH 81/82] chore: fixing knip report Signed-off-by: blam --- plugins/scaffolder-react/knip-report.md | 3 +-- plugins/scaffolder/knip-report.md | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/scaffolder-react/knip-report.md b/plugins/scaffolder-react/knip-report.md index 3d42235f5e..3c2e8f3c3c 100644 --- a/plugins/scaffolder-react/knip-report.md +++ b/plugins/scaffolder-react/knip-report.md @@ -1,12 +1,11 @@ # Knip report -## Unused dependencies (4) +## Unused dependencies (3) | Name | Location | Severity | | :------------------------ | :----------- | :------- | | @backstage/catalog-client | package.json | error | | zod-to-json-schema | package.json | error | -| immer | package.json | error | | zod | package.json | error | ## Unused devDependencies (2) diff --git a/plugins/scaffolder/knip-report.md b/plugins/scaffolder/knip-report.md index d130aaeb40..6004665f89 100644 --- a/plugins/scaffolder/knip-report.md +++ b/plugins/scaffolder/knip-report.md @@ -1,13 +1,12 @@ # Knip report -## Unused dependencies (4) +## Unused dependencies (3) | Name | Location | Severity | | :------------------ | :----------- | :------- | | json-schema-library | package.json | error | | @rjsf/material-ui | package.json | error | | git-url-parse | package.json | error | -| immer | package.json | error | ## Unused devDependencies (1) From 504b54e4dd8f42b0f7615b722bf34003045d562a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 16:57:26 +0000 Subject: [PATCH 82/82] Bump undici from 5.26.3 to 5.28.3 Bumps [undici](https://github.com/nodejs/undici) from 5.26.3 to 5.28.3. - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v5.26.3...v5.28.3) --- updated-dependencies: - dependency-name: undici dependency-type: indirect ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 82e03f005e..b612c502e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -44507,11 +44507,11 @@ __metadata: linkType: hard "undici@npm:^5.24.0": - version: 5.26.3 - resolution: "undici@npm:5.26.3" + version: 5.28.3 + resolution: "undici@npm:5.28.3" dependencies: "@fastify/busboy": ^2.0.0 - checksum: aaa9aadb712cf80e1a9cea2377e4842670105e00abbc184a21770ea5a8b77e4e2eadc200eac62442e74a1cd3b16a840c6f73b112b9e886bd3c1a125eb22e4f21 + checksum: fa1e65aff896c5e2ee23637b632e306f9e3a2b32a3dc0b23ea71e5555ad350bcc25713aea894b3dccc0b7dc2c5e92a5a58435ebc2033b731a5524506f573dfd2 languageName: node linkType: hard