From 0346703bafd24340a1583d3d0c2927100ddcb42b Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Tue, 24 Dec 2024 22:04:50 +0100 Subject: [PATCH 01/93] feat: initial general and generic chatbot to deploy infrastructure or artifacts from within the central repository --- .github/deploy-chatbot.yml | 122 +++++++++++++++++++++++++++++++++++++ README.md | 1 + 2 files changed, 123 insertions(+) create mode 100644 .github/deploy-chatbot.yml diff --git a/.github/deploy-chatbot.yml b/.github/deploy-chatbot.yml new file mode 100644 index 0000000..11389e0 --- /dev/null +++ b/.github/deploy-chatbot.yml @@ -0,0 +1,122 @@ +name: Handle PRE env deployment commands in PR Comments + +on: + issue_comment: + types: + - created + +jobs: + handle-slash-command: + runs-on: ubuntu-latest + + steps: + # Step 1: Parse Deployment Command + - name: Parse Deployment Command + id: parse_command + run: | + COMMENT_BODY="${{ github.event.comment.body }}" + echo "Comment received: $COMMENT_BODY" + + # Initialize variables + ENVIRONMENT="" + PROJECT="" + INFRA="" + + # Parse environment + if [[ "$COMMENT_BODY" =~ --environment[[:space:]]+([a-zA-Z0-9_-]+) ]]; then + ENVIRONMENT="${BASH_REMATCH[1]}" + echo "Environment: $ENVIRONMENT" + fi + + # Parse project + if [[ "$COMMENT_BODY" =~ --project[[:space:]]+\"([^\"]+)\" ]]; then + PROJECT="${BASH_REMATCH[1]}" + echo "Project: $PROJECT" + fi + + # Parse infra + if [[ "$COMMENT_BODY" =~ --infra[[:space:]]+([a-zA-Z0-9_-]+) ]]; then + INFRA="${BASH_REMATCH[1]}" + echo "Infra: $INFRA" + fi + + # Output parsed values + echo "environment=$ENVIRONMENT" >> $GITHUB_OUTPUT + echo "project=$PROJECT" >> $GITHUB_OUTPUT + echo "infra=$INFRA" >> $GITHUB_OUTPUT + + # Step 2: Validate and Trigger Deploy Workflow + - name: Trigger Deployment Workflow + if: steps.parse_command.outputs.environment != '' && steps.parse_command.outputs.project != '' + uses: actions/github-script@v6 + with: + script: | + const environment = `${{ steps.parse_command.outputs.environment }}`; + const project = `${{ steps.parse_command.outputs.project }}`; + const workflowId = `deploy-${environment}.yml`; + + console.log(`Triggering workflow: ${workflowId} for project: ${project}`); + + github.rest.actions.createWorkflowDispatch({ + owner: 'zerodaycode', + repo: project, + workflow_id: workflowId, + ref: 'main', // TODO: Change branch to ref + }); + + # Step 3: Deploy Infra (if requested) + - name: Deploy Infra + if: steps.parse_command.outputs.infra != '' + uses: appleboy/ssh-action@v0.1.5 + with: + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USERNAME }} + key: ${{ secrets.SSH_KEY }} + script: | + case "${{ steps.parse_command.outputs.infra }}" in + postgres) + echo "Deploying Postgres..." + docker run -d --name postgres --restart always -e POSTGRES_PASSWORD=mysecretpassword postgres + ;; + redis) + echo "Deploying Redis..." + docker run -d --name redis --restart always redis + ;; + all) + echo "Deploying Postgres and Redis..." + docker run -d --name postgres --restart always -e POSTGRES_PASSWORD=mysecretpassword postgres + docker run -d --name redis --restart always redis + ;; + *) + echo "Unknown infra: ${{ steps.parse_command.outputs.infra }}" + ;; + esac + + # Step 4: Post Confirmation Comment + - name: Post Comment to PR + uses: actions/github-script@v6 + with: + script: | + const environment = `${{ steps.parse_command.outputs.environment }}`; + const project = `${{ steps.parse_command.outputs.project }}`; + const infra = `${{ steps.parse_command.outputs.infra }}`; + const prNumber = context.payload.issue.number; + + let message = "🚀 Deployment triggered:\n"; + if (project) { + message += `- Project: \`${project}\`\n`; + } + if (environment) { + message += `- Environment: \`${environment}\`\n`; + } + if (infra) { + message += `- Infrastructure: \`${infra}\`\n`; + } + + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: message, + }); + diff --git a/README.md b/README.md index c84738a..7b31671 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ As an initial guideline, we intend this repo to look something similar to this app-summoner-sync/ ├── .github/ │ ├── workflows/ # GitHub Actions for deployment automation and repositories management +│ │ └── deploy-chatbot.yml │ │ └── deploy-pre.yml │ │ └── deploy-pro.yml ├── submodules/ # Includes microservice repositories From da92ce1b0459d98f6fe047c28083fce12dc96480 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Tue, 24 Dec 2024 22:11:25 +0100 Subject: [PATCH 02/93] feat: workflows folder --- .github/{ => workflows}/deploy-chatbot.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{ => workflows}/deploy-chatbot.yml (100%) diff --git a/.github/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml similarity index 100% rename from .github/deploy-chatbot.yml rename to .github/workflows/deploy-chatbot.yml From dd51b46d541a7879d98fefa0c97378626cf34ad6 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Tue, 24 Dec 2024 22:25:06 +0100 Subject: [PATCH 03/93] ci: updating the ssh-action version --- .github/workflows/deploy-chatbot.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 11389e0..3ae5be5 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -32,6 +32,7 @@ jobs: if [[ "$COMMENT_BODY" =~ --project[[:space:]]+\"([^\"]+)\" ]]; then PROJECT="${BASH_REMATCH[1]}" echo "Project: $PROJECT" + # TODO: else stopping the workflow if no env present fi # Parse infra @@ -45,6 +46,10 @@ jobs: echo "project=$PROJECT" >> $GITHUB_OUTPUT echo "infra=$INFRA" >> $GITHUB_OUTPUT + # TODO: from here, isolate them in independent workflows + # and just call them depending on the input by having just + # a simple and unique trigger deployment + # Step 2: Validate and Trigger Deploy Workflow - name: Trigger Deployment Workflow if: steps.parse_command.outputs.environment != '' && steps.parse_command.outputs.project != '' @@ -67,7 +72,7 @@ jobs: # Step 3: Deploy Infra (if requested) - name: Deploy Infra if: steps.parse_command.outputs.infra != '' - uses: appleboy/ssh-action@v0.1.5 + uses: appleboy/ssh-action@v1.2.0 with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USERNAME }} @@ -101,7 +106,7 @@ jobs: const project = `${{ steps.parse_command.outputs.project }}`; const infra = `${{ steps.parse_command.outputs.infra }}`; const prNumber = context.payload.issue.number; - + let message = "🚀 Deployment triggered:\n"; if (project) { message += `- Project: \`${project}\`\n`; From 4f5edb62b0d804f892a6c9fb6b5a33117d0372c0 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Tue, 24 Dec 2024 22:39:35 +0100 Subject: [PATCH 04/93] ci: debugging the step 1 of the parse command on step 2 --- .github/workflows/deploy-chatbot.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 3ae5be5..67c83b2 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -52,7 +52,6 @@ jobs: # Step 2: Validate and Trigger Deploy Workflow - name: Trigger Deployment Workflow - if: steps.parse_command.outputs.environment != '' && steps.parse_command.outputs.project != '' uses: actions/github-script@v6 with: script: | From f6783c21eeade0202afe204d7d9addd39989ddb8 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Tue, 24 Dec 2024 22:49:26 +0100 Subject: [PATCH 05/93] ci(fix): should correctly capture both the --environment and --project arguments when the command is provided --- .github/workflows/deploy-chatbot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 67c83b2..491a350 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -29,7 +29,7 @@ jobs: fi # Parse project - if [[ "$COMMENT_BODY" =~ --project[[:space:]]+\"([^\"]+)\" ]]; then + if [[ "$COMMENT_BODY" =~ --project[[:space:]]+([a-zA-Z0-9_-]+) ]]; then PROJECT="${BASH_REMATCH[1]}" echo "Project: $PROJECT" # TODO: else stopping the workflow if no env present From 13d8308b8c6bac9b2746db67dfd445c7b71d2325 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Wed, 25 Dec 2024 13:23:59 +0100 Subject: [PATCH 06/93] ci(local): Adding configuration for ACT to locally run the GH actions --- .actrc | 2 + .github/workflows/deploy-chatbot.yml | 81 +++++++++++++++++----------- .gitignore | 2 + 3 files changed, 53 insertions(+), 32 deletions(-) create mode 100644 .actrc diff --git a/.actrc b/.actrc new file mode 100644 index 0000000..f6ed481 --- /dev/null +++ b/.actrc @@ -0,0 +1,2 @@ +--action-offline-mode + diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 491a350..4d8358f 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -1,22 +1,29 @@ -name: Handle PRE env deployment commands in PR Comments +name: Handle deployment commands in PR Comments on: issue_comment: types: - created +permissions: + actions: write + jobs: handle-slash-command: runs-on: ubuntu-latest steps: - # Step 1: Parse Deployment Command - name: Parse Deployment Command id: parse_command run: | COMMENT_BODY="${{ github.event.comment.body }}" + if [[ "$env.ACT" ]]; then + echo "Setting the command as a mock since it's running locally with ACT" + COMMENT_BODY='/deploy --environment pre --project ag-summoners-sync' + fi + echo "Comment received: $COMMENT_BODY" - + # Initialize variables ENVIRONMENT="" PROJECT="" @@ -46,6 +53,42 @@ jobs: echo "project=$PROJECT" >> $GITHUB_OUTPUT echo "infra=$INFRA" >> $GITHUB_OUTPUT + - name: Notify the user + uses: actions/github-script@v6 + with: + script: | + const environment = `${{ steps.parse_command.outputs.environment }}`; + console.log(`ENVIRONMENT: ${environment}`); + const project = `${{ steps.parse_command.outputs.project }}`; + const infra = `${{ steps.parse_command.outputs.infra }}`; + + let message = "🚀 Deployment action received:\n"; + if (project) { + message += `- Project: \`${project}\`\n`; + } + if (environment) { + message += `- Environment: \`${environment}\`\n`; + } + if (infra) { + message += `- Infrastructure: \`${infra}\`\n`; + } + + if (${{ env.ACT }}) { + console.log(`Action is being runned locally by 'ACT'. + Skipping the notify user on PR, but output would have been: + ${message}`); + return; + } + + const prNumber = context.payload.issue.number; + + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: message, + }); + # TODO: from here, isolate them in independent workflows # and just call them depending on the input by having just # a simple and unique trigger deployment @@ -53,13 +96,15 @@ jobs: # Step 2: Validate and Trigger Deploy Workflow - name: Trigger Deployment Workflow uses: actions/github-script@v6 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: script: | const environment = `${{ steps.parse_command.outputs.environment }}`; const project = `${{ steps.parse_command.outputs.project }}`; const workflowId = `deploy-${environment}.yml`; - console.log(`Triggering workflow: ${workflowId} for project: ${project}`); + console.log(`🚀 Triggering workflow: ${workflowId} for project: ${project}`); github.rest.actions.createWorkflowDispatch({ owner: 'zerodaycode', @@ -96,31 +141,3 @@ jobs: ;; esac - # Step 4: Post Confirmation Comment - - name: Post Comment to PR - uses: actions/github-script@v6 - with: - script: | - const environment = `${{ steps.parse_command.outputs.environment }}`; - const project = `${{ steps.parse_command.outputs.project }}`; - const infra = `${{ steps.parse_command.outputs.infra }}`; - const prNumber = context.payload.issue.number; - - let message = "🚀 Deployment triggered:\n"; - if (project) { - message += `- Project: \`${project}\`\n`; - } - if (environment) { - message += `- Environment: \`${environment}\`\n`; - } - if (infra) { - message += `- Infrastructure: \`${infra}\`\n`; - } - - github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - body: message, - }); - diff --git a/.gitignore b/.gitignore index ddf87e0..2751a9c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ +.secrets + .nvim/ .idea/ From 3acc8187aa0ce943e37096e04c62d3f250a1e63e Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Wed, 25 Dec 2024 13:27:29 +0100 Subject: [PATCH 07/93] ci(local): Adding configuration for ACT to locally run the GH actions --- .github/workflows/deploy-chatbot.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 4d8358f..a833338 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -73,7 +73,9 @@ jobs: message += `- Infrastructure: \`${infra}\`\n`; } - if (${{ env.ACT }}) { + let localRun = ${{ env.ACT }} || false + + if (localRun) { console.log(`Action is being runned locally by 'ACT'. Skipping the notify user on PR, but output would have been: ${message}`); From dc99172f3a03914ecb299e505575df04fd768370 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Wed, 25 Dec 2024 13:28:47 +0100 Subject: [PATCH 08/93] ci: raising the github script version to 7 --- .github/workflows/deploy-chatbot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index a833338..7d199c7 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -54,7 +54,7 @@ jobs: echo "infra=$INFRA" >> $GITHUB_OUTPUT - name: Notify the user - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: | const environment = `${{ steps.parse_command.outputs.environment }}`; @@ -97,7 +97,7 @@ jobs: # Step 2: Validate and Trigger Deploy Workflow - name: Trigger Deployment Workflow - uses: actions/github-script@v6 + uses: actions/github-script@v7 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From ca75432cb85f04d6d320f5206c510bf31c8da808 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Wed, 25 Dec 2024 13:46:04 +0100 Subject: [PATCH 09/93] fix: wrong JS syntax for checking a non present env var on the cloud runners --- .github/workflows/deploy-chatbot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 7d199c7..99e3997 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -73,7 +73,7 @@ jobs: message += `- Infrastructure: \`${infra}\`\n`; } - let localRun = ${{ env.ACT }} || false + const localRun = `${{ env.ACT }}` === "true"; if (localRun) { console.log(`Action is being runned locally by 'ACT'. From d487c8f69269cef3f2f5303737ac79f9c07962ec Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Wed, 25 Dec 2024 13:58:05 +0100 Subject: [PATCH 10/93] chore(ci): avoiding to override the GITHUB_TOKEN var --- .github/workflows/deploy-chatbot.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 99e3997..42dbce7 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -98,8 +98,6 @@ jobs: # Step 2: Validate and Trigger Deploy Workflow - name: Trigger Deployment Workflow uses: actions/github-script@v7 - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: script: | const environment = `${{ steps.parse_command.outputs.environment }}`; From f957c65b998fb401899b8c96eeaf89d18d3312d3 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Wed, 25 Dec 2024 14:09:07 +0100 Subject: [PATCH 11/93] chore(ci): removing manually set permissions --- .github/workflows/deploy-chatbot.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 42dbce7..cf67e13 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -5,9 +5,6 @@ on: types: - created -permissions: - actions: write - jobs: handle-slash-command: runs-on: ubuntu-latest From b83cd3c8711056994fa4be6de84f6939e4c7ebce Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Wed, 25 Dec 2024 17:31:33 +0100 Subject: [PATCH 12/93] ci: getting org oauth from the zdc's app --- .actrc | 3 +-- .github/workflows/deploy-chatbot.yml | 15 ++++++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.actrc b/.actrc index f6ed481..c36d7de 100644 --- a/.actrc +++ b/.actrc @@ -1,2 +1 @@ ---action-offline-mode - +--action-offline-mode \ No newline at end of file diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index cf67e13..32c0ba5 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -6,7 +6,7 @@ on: - created jobs: - handle-slash-command: + handle-deployment-on-pr-comment: runs-on: ubuntu-latest steps: @@ -50,12 +50,19 @@ jobs: echo "project=$PROJECT" >> $GITHUB_OUTPUT echo "infra=$INFRA" >> $GITHUB_OUTPUT + - name: Get GH Zero Day Code APP token + uses: actions/create-github-app-token@v1 + id: zdc-app-token + with: + app-id: ${{ vars.ZDC_AUTH_APP_ID }} + private-key: ${{ secrets.ZDC_AUTH_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + - name: Notify the user uses: actions/github-script@v7 with: script: | const environment = `${{ steps.parse_command.outputs.environment }}`; - console.log(`ENVIRONMENT: ${environment}`); const project = `${{ steps.parse_command.outputs.project }}`; const infra = `${{ steps.parse_command.outputs.infra }}`; @@ -92,7 +99,6 @@ jobs: # and just call them depending on the input by having just # a simple and unique trigger deployment - # Step 2: Validate and Trigger Deploy Workflow - name: Trigger Deployment Workflow uses: actions/github-script@v7 with: @@ -104,13 +110,12 @@ jobs: console.log(`🚀 Triggering workflow: ${workflowId} for project: ${project}`); github.rest.actions.createWorkflowDispatch({ - owner: 'zerodaycode', + owner: context.repo.owner, repo: project, workflow_id: workflowId, ref: 'main', // TODO: Change branch to ref }); - # Step 3: Deploy Infra (if requested) - name: Deploy Infra if: steps.parse_command.outputs.infra != '' uses: appleboy/ssh-action@v1.2.0 From 75180265f76f8712a0c4284c1d9adddc657e272f Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Wed, 25 Dec 2024 18:17:49 +0100 Subject: [PATCH 13/93] ci: adding the new JWT token form the auth app to the run workflow on other repo step --- .github/workflows/deploy-chatbot.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 32c0ba5..80a39c8 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -11,6 +11,7 @@ jobs: steps: - name: Parse Deployment Command + if: ${{ !env.ACT }} id: parse_command run: | COMMENT_BODY="${{ github.event.comment.body }}" @@ -52,7 +53,7 @@ jobs: - name: Get GH Zero Day Code APP token uses: actions/create-github-app-token@v1 - id: zdc-app-token + id: zdc-auth-app-token with: app-id: ${{ vars.ZDC_AUTH_APP_ID }} private-key: ${{ secrets.ZDC_AUTH_PRIVATE_KEY }} @@ -102,6 +103,7 @@ jobs: - name: Trigger Deployment Workflow uses: actions/github-script@v7 with: + github-token: ${{ steps.zdc-auth-app-token.outputs.token }} script: | const environment = `${{ steps.parse_command.outputs.environment }}`; const project = `${{ steps.parse_command.outputs.project }}`; From 3f985a16c74efc2b7525bd88fe45c25f2d032520 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Wed, 25 Dec 2024 21:51:49 +0100 Subject: [PATCH 14/93] ci: better configuration for using the ZDC Auth Oauth app in the cloud or PATs on local envs --- .github/workflows/deploy-chatbot.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 80a39c8..8a16114 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -11,7 +11,6 @@ jobs: steps: - name: Parse Deployment Command - if: ${{ !env.ACT }} id: parse_command run: | COMMENT_BODY="${{ github.event.comment.body }}" @@ -37,7 +36,9 @@ jobs: if [[ "$COMMENT_BODY" =~ --project[[:space:]]+([a-zA-Z0-9_-]+) ]]; then PROJECT="${BASH_REMATCH[1]}" echo "Project: $PROJECT" - # TODO: else stopping the workflow if no env present + else + echo "No environment specified. Aborting workflow." + exit 1 # Aborts the workflow # TODO: pass it as an output to the user notifier step fi # Parse infra @@ -52,6 +53,7 @@ jobs: echo "infra=$INFRA" >> $GITHUB_OUTPUT - name: Get GH Zero Day Code APP token + if: ${{ !env.ACT }} uses: actions/create-github-app-token@v1 id: zdc-auth-app-token with: @@ -67,7 +69,10 @@ jobs: const project = `${{ steps.parse_command.outputs.project }}`; const infra = `${{ steps.parse_command.outputs.infra }}`; - let message = "🚀 Deployment action received:\n"; + const actor = `${{ github.event.comment.user.login }}`; + const username = (actor !== "") ? actor : 'Unknown'; + + let message = `🚀 Deployment action request received from user: ${username}\n`; if (project) { message += `- Project: \`${project}\`\n`; } @@ -103,19 +108,17 @@ jobs: - name: Trigger Deployment Workflow uses: actions/github-script@v7 with: - github-token: ${{ steps.zdc-auth-app-token.outputs.token }} + github-token: ${{ steps.zdc-auth-app-token.outputs.token || github.token }} script: | const environment = `${{ steps.parse_command.outputs.environment }}`; const project = `${{ steps.parse_command.outputs.project }}`; const workflowId = `deploy-${environment}.yml`; - console.log(`🚀 Triggering workflow: ${workflowId} for project: ${project}`); - github.rest.actions.createWorkflowDispatch({ owner: context.repo.owner, repo: project, workflow_id: workflowId, - ref: 'main', // TODO: Change branch to ref + ref: 'main', // TODO: Change branch to ref if pre, otherwise PRO should be only on main }); - name: Deploy Infra From e963d011dfe00d9960ad1e7f97d4102905474109 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Thu, 26 Dec 2024 17:43:28 +0100 Subject: [PATCH 15/93] ci: updating the message with the workflow status after being triggered --- .actrc | 3 +- .github/workflows/deploy-chatbot.yml | 93 ++++++++++++++----- .../workflows/mock_payloads/deploy_act.json | 18 ++++ 3 files changed, 92 insertions(+), 22 deletions(-) create mode 100644 .github/workflows/mock_payloads/deploy_act.json diff --git a/.actrc b/.actrc index c36d7de..e83d2f2 100644 --- a/.actrc +++ b/.actrc @@ -1 +1,2 @@ ---action-offline-mode \ No newline at end of file +--action-offline-mode +-e .github/workflows/mock_payloads/deploy_act.json \ No newline at end of file diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 8a16114..145843d 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -13,8 +13,9 @@ jobs: - name: Parse Deployment Command id: parse_command run: | + WORKFLOW_LOCAL_RUN="${{ !github.event.act }}" COMMENT_BODY="${{ github.event.comment.body }}" - if [[ "$env.ACT" ]]; then + if [[ WORKFLOW_LOCAL_RUN ]]; then echo "Setting the command as a mock since it's running locally with ACT" COMMENT_BODY='/deploy --environment pre --project ag-summoners-sync' fi @@ -53,7 +54,7 @@ jobs: echo "infra=$INFRA" >> $GITHUB_OUTPUT - name: Get GH Zero Day Code APP token - if: ${{ !env.ACT }} + if: ${{ !github.event.act }} uses: actions/create-github-app-token@v1 id: zdc-auth-app-token with: @@ -63,6 +64,7 @@ jobs: - name: Notify the user uses: actions/github-script@v7 + id: notify_user with: script: | const environment = `${{ steps.parse_command.outputs.environment }}`; @@ -72,6 +74,8 @@ jobs: const actor = `${{ github.event.comment.user.login }}`; const username = (actor !== "") ? actor : 'Unknown'; + const prNumber = context.payload.issue.number; + let message = `🚀 Deployment action request received from user: ${username}\n`; if (project) { message += `- Project: \`${project}\`\n`; @@ -83,30 +87,29 @@ jobs: message += `- Infrastructure: \`${infra}\`\n`; } - const localRun = `${{ env.ACT }}` === "true"; - - if (localRun) { + if (${{ github.event.act }}) { console.log(`Action is being runned locally by 'ACT'. Skipping the notify user on PR, but output would have been: ${message}`); - return; + return { comment_id: 10 } // arbitraty mocked comment number; + } else { + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: message, + }); + console.log(`Comment REST returned data: ${JSON.stringify(comment, null, 2)}`); + return { "comment_id": comment.data.id }; } - const prNumber = context.payload.issue.number; - - github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - body: message, - }); - # TODO: from here, isolate them in independent workflows # and just call them depending on the input by having just # a simple and unique trigger deployment - name: Trigger Deployment Workflow uses: actions/github-script@v7 + id: trigger_deployment_workflow with: github-token: ${{ steps.zdc-auth-app-token.outputs.token || github.token }} script: | @@ -114,12 +117,30 @@ jobs: const project = `${{ steps.parse_command.outputs.project }}`; const workflowId = `deploy-${environment}.yml`; - github.rest.actions.createWorkflowDispatch({ - owner: context.repo.owner, - repo: project, - workflow_id: workflowId, - ref: 'main', // TODO: Change branch to ref if pre, otherwise PRO should be only on main - }); + let result = ""; + let details = ""; + + try { + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: project, + workflow_id: workflowId, + ref: 'main', // TODO: Change branch to ref if pre, otherwise PRO should be only on main + }); + status = 'OK'; + details = 'succedeed'; + } catch (ex) { + console.log(`FAILED TO TRIGGER WORKFLOW:\n${ex}`); + status = 'ERR'; + details = `Failed to trigger the workflow ${workflowId} on repo: ${project}`; + } + + // Return triggered details + return { + workflow_name: workflowId, + status: status, + details: details, + }; - name: Deploy Infra if: steps.parse_command.outputs.infra != '' @@ -148,3 +169,33 @@ jobs: ;; esac + - name: Update Deployment Status + uses: actions/github-script@v7 + id: update-comment-with-deployment-status + with: + script: | + const workflowLocalRun = ${{ github.event.act }}; + + const commentOnPr = `${{ steps.notify_user.outputs.result }}`; + const commentId = JSON.parse(commentOnPr).comment_id; + console.log(`Updating comment with id ${commentId} for workflow status`); + + const workflowDispatchResult = `${{ steps.trigger_deployment_workflow.outputs.result }}`; + console.log(`Trigger deployment status: ${workflowDispatchResult}`); + const workflowDetails = JSON.parse(workflowDispatchResult); + + const runUrl = ""; // TODO: empty for now + + const statusIcon = workflowDetails.status === 'OK' ? '✅' : '❌'; + const statusMsg = workflowDetails.details; + const message = `${statusIcon} Deployment ${statusMsg}. [View Workflow](${runUrl})`; + console.log(message); + + if (!workflowLocalRun) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: commentId, + body: message, + }); + } diff --git a/.github/workflows/mock_payloads/deploy_act.json b/.github/workflows/mock_payloads/deploy_act.json new file mode 100644 index 0000000..3c3da08 --- /dev/null +++ b/.github/workflows/mock_payloads/deploy_act.json @@ -0,0 +1,18 @@ +{ + "act": true, + "comment": { + "body": "/deploy --environment pre --project ag-summoners-sync", + "user": { + "login": "TheRustifyer" + } + }, + "issue": { + "number": 4 + }, + "repository": { + "name": "app-summoners-sync", + "owner": { + "login": "zerodaycode" + } + } + } \ No newline at end of file From 9618e307867340ea4ad517fd54be8435e7f2479e Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Thu, 26 Dec 2024 18:17:01 +0100 Subject: [PATCH 16/93] fix: missing 'truthy' boolean comparisons on empty substitutions --force --- .github/workflows/deploy-chatbot.yml | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 145843d..a9ef2a7 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -87,20 +87,25 @@ jobs: message += `- Infrastructure: \`${infra}\`\n`; } - if (${{ github.event.act }}) { + if (`${{ github.event.act }}` === 'true') { console.log(`Action is being runned locally by 'ACT'. Skipping the notify user on PR, but output would have been: ${message}`); return { comment_id: 10 } // arbitraty mocked comment number; } else { - github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - body: message, - }); - console.log(`Comment REST returned data: ${JSON.stringify(comment, null, 2)}`); - return { "comment_id": comment.data.id }; + let comment = {}; + try { + comment = await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: message, + }); + return { "comment_id": comment.data.id }; + } catch (ex) { + console.log("Failed to POST the comment on the PR to notify the user due to =[> " + ex + "]"); + return { "comment_id": null }; + } } # TODO: from here, isolate them in independent workflows @@ -174,7 +179,7 @@ jobs: id: update-comment-with-deployment-status with: script: | - const workflowLocalRun = ${{ github.event.act }}; + const workflowLocalRun = `${{ github.event.act }}` === 'true'; const commentOnPr = `${{ steps.notify_user.outputs.result }}`; const commentId = JSON.parse(commentOnPr).comment_id; From b4be2ef2c4d54cfa72feaff85d9d418e8a977f06 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Thu, 26 Dec 2024 18:34:34 +0100 Subject: [PATCH 17/93] feat: Introducing a new step on the action to retrieve the running workflows on the target project --- .github/workflows/deploy-chatbot.yml | 77 ++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 20 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index a9ef2a7..8201ae6 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Parse Deployment Command - id: parse_command + id: parse-command run: | WORKFLOW_LOCAL_RUN="${{ !github.event.act }}" COMMENT_BODY="${{ github.event.comment.body }}" @@ -64,12 +64,12 @@ jobs: - name: Notify the user uses: actions/github-script@v7 - id: notify_user + id: notify-user with: script: | - const environment = `${{ steps.parse_command.outputs.environment }}`; - const project = `${{ steps.parse_command.outputs.project }}`; - const infra = `${{ steps.parse_command.outputs.infra }}`; + const environment = `${{ steps.parse-command.outputs.environment }}`; + const project = `${{ steps.parse-command.outputs.project }}`; + const infra = `${{ steps.parse-command.outputs.infra }}`; const actor = `${{ github.event.comment.user.login }}`; const username = (actor !== "") ? actor : 'Unknown'; @@ -91,7 +91,7 @@ jobs: console.log(`Action is being runned locally by 'ACT'. Skipping the notify user on PR, but output would have been: ${message}`); - return { comment_id: 10 } // arbitraty mocked comment number; + return { comment_id: 10, message: message } // arbitraty mocked comment number; } else { let comment = {}; try { @@ -101,7 +101,7 @@ jobs: issue_number: prNumber, body: message, }); - return { "comment_id": comment.data.id }; + return { comment_id: comment.data.id, message: message }; } catch (ex) { console.log("Failed to POST the comment on the PR to notify the user due to =[> " + ex + "]"); return { "comment_id": null }; @@ -114,12 +114,12 @@ jobs: - name: Trigger Deployment Workflow uses: actions/github-script@v7 - id: trigger_deployment_workflow + id: trigger-deployment-workflow with: github-token: ${{ steps.zdc-auth-app-token.outputs.token || github.token }} script: | - const environment = `${{ steps.parse_command.outputs.environment }}`; - const project = `${{ steps.parse_command.outputs.project }}`; + const environment = `${{ steps.parse-command.outputs.environment }}`; + const project = `${{ steps.parse-command.outputs.project }}`; const workflowId = `deploy-${environment}.yml`; let result = ""; @@ -142,20 +142,20 @@ jobs: // Return triggered details return { - workflow_name: workflowId, + workflowId: workflowId, status: status, details: details, }; - name: Deploy Infra - if: steps.parse_command.outputs.infra != '' + if: steps.parse-command.outputs.infra != '' uses: appleboy/ssh-action@v1.2.0 with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USERNAME }} key: ${{ secrets.SSH_KEY }} script: | - case "${{ steps.parse_command.outputs.infra }}" in + case "${{ steps.parse-command.outputs.infra }}" in postgres) echo "Deploying Postgres..." docker run -d --name postgres --restart always -e POSTGRES_PASSWORD=mysecretpassword postgres @@ -170,7 +170,7 @@ jobs: docker run -d --name redis --restart always redis ;; *) - echo "Unknown infra: ${{ steps.parse_command.outputs.infra }}" + echo "Unknown infra: ${{ steps.parse-command.outputs.infra }}" ;; esac @@ -181,19 +181,20 @@ jobs: script: | const workflowLocalRun = `${{ github.event.act }}` === 'true'; - const commentOnPr = `${{ steps.notify_user.outputs.result }}`; - const commentId = JSON.parse(commentOnPr).comment_id; + const commentOnPr = ${{ steps.notify-user.outputs.result }}; + const commentId = commentOnPr.comment_id; console.log(`Updating comment with id ${commentId} for workflow status`); - const workflowDispatchResult = `${{ steps.trigger_deployment_workflow.outputs.result }}`; - console.log(`Trigger deployment status: ${workflowDispatchResult}`); - const workflowDetails = JSON.parse(workflowDispatchResult); + const workflowDetails = ${{ steps.trigger-deployment-workflow.outputs.result }}; + console.log(`Trigger deployment status: ${JSON.stringify(workflowDetails, null, 2)}`); const runUrl = ""; // TODO: empty for now const statusIcon = workflowDetails.status === 'OK' ? '✅' : '❌'; const statusMsg = workflowDetails.details; - const message = `${statusIcon} Deployment ${statusMsg}. [View Workflow](${runUrl})`; + + const previousMsgData = commentOnPr.message; + const message = `${previousMsgData}\n${statusIcon} Deployment ${statusMsg}. [View Workflow](${runUrl})`; console.log(message); if (!workflowLocalRun) { @@ -204,3 +205,39 @@ jobs: body: message, }); } + + - name: Wait for Deployment + id: wait-for-deployment + uses: actions/github-script@v7 + with: + script: | + const project = `${{ steps.trigger-deployment-workflow.outputs.project }}`; + const workflowName = `${{ steps.trigger-deployment-workflow.outputs.workflowId }}`; + const pollInterval = 10 * 1000; // 10 seconds + + console.log(`Polling for workflow status: ${workflowName} in ${project}`); + + let status = 'in_progress'; + let conclusion = ''; + while (status === 'in_progress') { + const runs = await github.rest.actions.listWorkflowRuns({ + owner: context.repo.owner, + repo: project, + workflow_id: workflowName, + branch: 'main', + status: 'in_progress', + }); + + if (runs.data.workflow_runs.length > 0) { + const run = runs.data.workflow_runs[0]; // TODO: not really take the first one, should be fix later + status = run.status; + conclusion = run.conclusion; + + if (status === 'completed') { + console.log(`Workflow completed with status: ${conclusion}`); + return { status: conclusion, run_url: run.html_url }; + } + } + + await new Promise(resolve => setTimeout(resolve, pollInterval)); + } From 273e419a9ba65685257d0ef21630703ba5ca32fb Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Thu, 26 Dec 2024 20:43:09 +0100 Subject: [PATCH 18/93] feat(ci): completed the basic approach to launch a deploy on an artifact on other project/repo --- .github/workflows/deploy-chatbot.yml | 40 +++------------------------- 1 file changed, 3 insertions(+), 37 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 8201ae6..4feaf07 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -188,7 +188,9 @@ jobs: const workflowDetails = ${{ steps.trigger-deployment-workflow.outputs.result }}; console.log(`Trigger deployment status: ${JSON.stringify(workflowDetails, null, 2)}`); - const runUrl = ""; // TODO: empty for now + const owner = `${{ github.event.repository.owner.login }}`; + const project = `${{ github.event.repository.name }}`; + const runUrl = `https://github.com/${owner}/${project}/actions`; const statusIcon = workflowDetails.status === 'OK' ? '✅' : '❌'; const statusMsg = workflowDetails.details; @@ -205,39 +207,3 @@ jobs: body: message, }); } - - - name: Wait for Deployment - id: wait-for-deployment - uses: actions/github-script@v7 - with: - script: | - const project = `${{ steps.trigger-deployment-workflow.outputs.project }}`; - const workflowName = `${{ steps.trigger-deployment-workflow.outputs.workflowId }}`; - const pollInterval = 10 * 1000; // 10 seconds - - console.log(`Polling for workflow status: ${workflowName} in ${project}`); - - let status = 'in_progress'; - let conclusion = ''; - while (status === 'in_progress') { - const runs = await github.rest.actions.listWorkflowRuns({ - owner: context.repo.owner, - repo: project, - workflow_id: workflowName, - branch: 'main', - status: 'in_progress', - }); - - if (runs.data.workflow_runs.length > 0) { - const run = runs.data.workflow_runs[0]; // TODO: not really take the first one, should be fix later - status = run.status; - conclusion = run.conclusion; - - if (status === 'completed') { - console.log(`Workflow completed with status: ${conclusion}`); - return { status: conclusion, run_url: run.html_url }; - } - } - - await new Promise(resolve => setTimeout(resolve, pollInterval)); - } From 447153b1c5e9eac75f2f32da0533b71eb3526700 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Thu, 26 Dec 2024 20:45:23 +0100 Subject: [PATCH 19/93] fix(ci): wrong upstream url project --- .github/workflows/deploy-chatbot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 4feaf07..3fd3de4 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -189,7 +189,7 @@ jobs: console.log(`Trigger deployment status: ${JSON.stringify(workflowDetails, null, 2)}`); const owner = `${{ github.event.repository.owner.login }}`; - const project = `${{ github.event.repository.name }}`; + const project = `${{ steps.parse-command.outputs.project }}`; const runUrl = `https://github.com/${owner}/${project}/actions`; const statusIcon = workflowDetails.status === 'OK' ? '✅' : '❌'; From 71daa3d8f4168a44b0f1f5699bec49e47b18ef79 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Thu, 26 Dec 2024 23:36:34 +0100 Subject: [PATCH 20/93] ci: refactoring steps with scripts with inlined JS into JS modules --- .github/workflows/deploy-chatbot.yml | 58 ++++++---------------------- actions_scripts/notify_user.js | 47 ++++++++++++++++++++++ 2 files changed, 58 insertions(+), 47 deletions(-) create mode 100644 actions_scripts/notify_user.js diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 3fd3de4..629781b 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Parse Deployment Command - id: parse-command + id: parse_command run: | WORKFLOW_LOCAL_RUN="${{ !github.event.act }}" COMMENT_BODY="${{ github.event.comment.body }}" @@ -62,51 +62,15 @@ jobs: private-key: ${{ secrets.ZDC_AUTH_PRIVATE_KEY }} owner: ${{ github.repository_owner }} + - uses: actions/checkout@v4 + - name: Notify the user uses: actions/github-script@v7 id: notify-user with: script: | - const environment = `${{ steps.parse-command.outputs.environment }}`; - const project = `${{ steps.parse-command.outputs.project }}`; - const infra = `${{ steps.parse-command.outputs.infra }}`; - - const actor = `${{ github.event.comment.user.login }}`; - const username = (actor !== "") ? actor : 'Unknown'; - - const prNumber = context.payload.issue.number; - - let message = `🚀 Deployment action request received from user: ${username}\n`; - if (project) { - message += `- Project: \`${project}\`\n`; - } - if (environment) { - message += `- Environment: \`${environment}\`\n`; - } - if (infra) { - message += `- Infrastructure: \`${infra}\`\n`; - } - - if (`${{ github.event.act }}` === 'true') { - console.log(`Action is being runned locally by 'ACT'. - Skipping the notify user on PR, but output would have been: - ${message}`); - return { comment_id: 10, message: message } // arbitraty mocked comment number; - } else { - let comment = {}; - try { - comment = await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - body: message, - }); - return { comment_id: comment.data.id, message: message }; - } catch (ex) { - console.log("Failed to POST the comment on the PR to notify the user due to =[> " + ex + "]"); - return { "comment_id": null }; - } - } + const script = require('./actions_scripts/notify_user.js') + await script({github, context, steps}) # TODO: from here, isolate them in independent workflows # and just call them depending on the input by having just @@ -118,8 +82,8 @@ jobs: with: github-token: ${{ steps.zdc-auth-app-token.outputs.token || github.token }} script: | - const environment = `${{ steps.parse-command.outputs.environment }}`; - const project = `${{ steps.parse-command.outputs.project }}`; + const environment = `${{ steps.parse_command.outputs.environment }}`; + const project = `${{ steps.parse_command.outputs.project }}`; const workflowId = `deploy-${environment}.yml`; let result = ""; @@ -148,14 +112,14 @@ jobs: }; - name: Deploy Infra - if: steps.parse-command.outputs.infra != '' + if: steps.parse_command.outputs.infra != '' uses: appleboy/ssh-action@v1.2.0 with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USERNAME }} key: ${{ secrets.SSH_KEY }} script: | - case "${{ steps.parse-command.outputs.infra }}" in + case "${{ steps.parse_command.outputs.infra }}" in postgres) echo "Deploying Postgres..." docker run -d --name postgres --restart always -e POSTGRES_PASSWORD=mysecretpassword postgres @@ -170,7 +134,7 @@ jobs: docker run -d --name redis --restart always redis ;; *) - echo "Unknown infra: ${{ steps.parse-command.outputs.infra }}" + echo "Unknown infra: ${{ steps.parse_command.outputs.infra }}" ;; esac @@ -189,7 +153,7 @@ jobs: console.log(`Trigger deployment status: ${JSON.stringify(workflowDetails, null, 2)}`); const owner = `${{ github.event.repository.owner.login }}`; - const project = `${{ steps.parse-command.outputs.project }}`; + const project = `${{ steps.parse_command.outputs.project }}`; const runUrl = `https://github.com/${owner}/${project}/actions`; const statusIcon = workflowDetails.status === 'OK' ? '✅' : '❌'; diff --git a/actions_scripts/notify_user.js b/actions_scripts/notify_user.js new file mode 100644 index 0000000..481f23b --- /dev/null +++ b/actions_scripts/notify_user.js @@ -0,0 +1,47 @@ +module.exports = async ({github, context, steps}) => { + console.log(`GITHUB: ${JSON.stringify(github, null, 2)}`); + console.log(`CTX: ${JSON.stringify(context, null, 2)}`); + console.log(`STEPS: ${JSON.stringify(steps, null, 2)}`); + + const environment = steps.parse_command.outputs.environment; + const project = steps.parse_command.outputs.project; + const infra = steps.parse_command.outputs.infra; + + const actor = github.event.comment.user.login; + console.log(`Actor: ${actor}`) + const username = (actor !== "") ? actor : 'Unknown'; + + const prNumber = context.payload.issue.number; + + let message = `🚀 Deployment action request received from user: ${username}\n`; + if (project) { + message += `- Project: \`${project}\`\n`; + } + if (environment) { + message += `- Environment: \`${environment}\`\n`; + } + if (infra) { + message += `- Infrastructure: \`${infra}\`\n`; + } + + if (`${ github.event.act }` === 'true') { + console.log(`Action is being runned locally by 'ACT'. + Skipping the notify user on PR, but output would have been: + ${message}`); + return { comment_id: 10, message: message } // arbitraty mocked comment number; + } else { + let comment = {}; + try { + comment = await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: message, + }); + return { comment_id: comment.data.id, message: message }; + } catch (ex) { + console.log("Failed to POST the comment on the PR to notify the user due to =[> " + ex + "]"); + return { "comment_id": null }; + } + } +} \ No newline at end of file From 149eb6725a753f464bd8aba27620df81dbebbedb Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Thu, 26 Dec 2024 23:51:42 +0100 Subject: [PATCH 21/93] ci: logging the data that we can pass to the action --- .github/workflows/deploy-chatbot.yml | 3 ++- actions_scripts/notify_user.js | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 629781b..8fef45c 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -69,8 +69,9 @@ jobs: id: notify-user with: script: | + console.log(context) const script = require('./actions_scripts/notify_user.js') - await script({github, context, steps}) + await script({github, context}) # TODO: from here, isolate them in independent workflows # and just call them depending on the input by having just diff --git a/actions_scripts/notify_user.js b/actions_scripts/notify_user.js index 481f23b..51d10f4 100644 --- a/actions_scripts/notify_user.js +++ b/actions_scripts/notify_user.js @@ -1,7 +1,10 @@ module.exports = async ({github, context, steps}) => { console.log(`GITHUB: ${JSON.stringify(github, null, 2)}`); console.log(`CTX: ${JSON.stringify(context, null, 2)}`); - console.log(`STEPS: ${JSON.stringify(steps, null, 2)}`); + console.log(`process: ${JSON.stringify(process.env, null, 2)}`); + const {SHA} = process.env + console.log(`SHA: ${SHA}`) + // console.log(`STEPS: ${JSON.stringify(steps, null, 2)}`); const environment = steps.parse_command.outputs.environment; const project = steps.parse_command.outputs.project; From 051a99698c7fafcf0e508daafc1dd2d10cdb4c23 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Fri, 27 Dec 2024 11:29:44 +0100 Subject: [PATCH 22/93] ci: workaround for the undefined steps --- .github/workflows/deploy-chatbot.yml | 3 ++- actions_scripts/notify_user.js | 15 +++------------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 8fef45c..e9aa0f5 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -69,7 +69,8 @@ jobs: id: notify-user with: script: | - console.log(context) + console.log(github) + console.log(`GITHUB: ${JSON.stringify(github, null, 2)}`); const script = require('./actions_scripts/notify_user.js') await script({github, context}) diff --git a/actions_scripts/notify_user.js b/actions_scripts/notify_user.js index 51d10f4..e21a4a7 100644 --- a/actions_scripts/notify_user.js +++ b/actions_scripts/notify_user.js @@ -1,16 +1,7 @@ -module.exports = async ({github, context, steps}) => { - console.log(`GITHUB: ${JSON.stringify(github, null, 2)}`); +module.exports = async ({github, context, environment, project, infra}) => { console.log(`CTX: ${JSON.stringify(context, null, 2)}`); - console.log(`process: ${JSON.stringify(process.env, null, 2)}`); - const {SHA} = process.env - console.log(`SHA: ${SHA}`) - // console.log(`STEPS: ${JSON.stringify(steps, null, 2)}`); - const environment = steps.parse_command.outputs.environment; - const project = steps.parse_command.outputs.project; - const infra = steps.parse_command.outputs.infra; - - const actor = github.event.comment.user.login; + const actor = context.actor; console.log(`Actor: ${actor}`) const username = (actor !== "") ? actor : 'Unknown'; @@ -27,7 +18,7 @@ module.exports = async ({github, context, steps}) => { message += `- Infrastructure: \`${infra}\`\n`; } - if (`${ github.event.act }` === 'true') { + if (context.payload.act === 'true') { console.log(`Action is being runned locally by 'ACT'. Skipping the notify user on PR, but output would have been: ${message}`); From 84cdfd9e609eabf52cadb3aaaa0afe94fe3f1da5 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Fri, 27 Dec 2024 12:12:25 +0100 Subject: [PATCH 23/93] ci(fix): solving weird action context to JS syntax empty conversions --- .github/workflows/deploy-chatbot.yml | 26 +- .../workflows/mock_payloads/deploy_act.json | 315 +++++++++++++++++- actions_scripts/notify_user.js | 12 +- 3 files changed, 323 insertions(+), 30 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index e9aa0f5..7452f8d 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Parse Deployment Command - id: parse_command + id: parse-command run: | WORKFLOW_LOCAL_RUN="${{ !github.event.act }}" COMMENT_BODY="${{ github.event.comment.body }}" @@ -69,10 +69,13 @@ jobs: id: notify-user with: script: | - console.log(github) - console.log(`GITHUB: ${JSON.stringify(github, null, 2)}`); const script = require('./actions_scripts/notify_user.js') - await script({github, context}) + + const environment = `${{ steps.parse-command.outputs.result.environment }}`; + const project = `${{ steps.parse-command.outputs.result.project }}`; + const infra = `${{ steps.parse-command.outputs.result.infra }}`; + + return await script({github, context, environment, project, infra}) # TODO: from here, isolate them in independent workflows # and just call them depending on the input by having just @@ -84,8 +87,8 @@ jobs: with: github-token: ${{ steps.zdc-auth-app-token.outputs.token || github.token }} script: | - const environment = `${{ steps.parse_command.outputs.environment }}`; - const project = `${{ steps.parse_command.outputs.project }}`; + const environment = `${{ steps.parse-command.outputs.environment }}`; + const project = `${{ steps.parse-command.outputs.project }}`; const workflowId = `deploy-${environment}.yml`; let result = ""; @@ -114,14 +117,14 @@ jobs: }; - name: Deploy Infra - if: steps.parse_command.outputs.infra != '' + if: steps.parse-command.outputs.infra != '' uses: appleboy/ssh-action@v1.2.0 with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USERNAME }} key: ${{ secrets.SSH_KEY }} script: | - case "${{ steps.parse_command.outputs.infra }}" in + case "${{ steps.parse-command.outputs.infra }}" in postgres) echo "Deploying Postgres..." docker run -d --name postgres --restart always -e POSTGRES_PASSWORD=mysecretpassword postgres @@ -136,7 +139,7 @@ jobs: docker run -d --name redis --restart always redis ;; *) - echo "Unknown infra: ${{ steps.parse_command.outputs.infra }}" + echo "Unknown infra: ${{ steps.parse-command.outputs.infra }}" ;; esac @@ -146,8 +149,9 @@ jobs: with: script: | const workflowLocalRun = `${{ github.event.act }}` === 'true'; + console.log("Is local run: " + workflowLocalRun); - const commentOnPr = ${{ steps.notify-user.outputs.result }}; + const commentOnPr = JSON.parse(`${{ steps.notify-user.outputs.result }}`); const commentId = commentOnPr.comment_id; console.log(`Updating comment with id ${commentId} for workflow status`); @@ -155,7 +159,7 @@ jobs: console.log(`Trigger deployment status: ${JSON.stringify(workflowDetails, null, 2)}`); const owner = `${{ github.event.repository.owner.login }}`; - const project = `${{ steps.parse_command.outputs.project }}`; + const project = `${{ steps.parse-command.outputs.project }}`; const runUrl = `https://github.com/${owner}/${project}/actions`; const statusIcon = workflowDetails.status === 'OK' ? '✅' : '❌'; diff --git a/.github/workflows/mock_payloads/deploy_act.json b/.github/workflows/mock_payloads/deploy_act.json index 3c3da08..6aa8a20 100644 --- a/.github/workflows/mock_payloads/deploy_act.json +++ b/.github/workflows/mock_payloads/deploy_act.json @@ -1,18 +1,307 @@ { - "act": true, - "comment": { - "body": "/deploy --environment pre --project ag-summoners-sync", - "user": { - "login": "TheRustifyer" - } + "act": true, + "action": "created", + "comment": { + "author_association": "MEMBER", + "body": "/deploy --environment pre --project ag-summoners-sync", + "created_at": "2024-12-27T10:30:39Z", + "html_url": "https://github.com/zerodaycode/app-summoners-sync/pull/4#issuecomment-2563559471", + "id": 2563559471, + "issue_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/issues/4", + "node_id": "IC_kwDONduBec6YzNAv", + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/issues/comments/2563559471/reactions" }, - "issue": { - "number": 4 + "updated_at": "2024-12-27T10:30:39Z", + "url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/issues/comments/2563559471", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/68871459?v=4", + "events_url": "https://api.github.com/users/TheRustifyer/events{/privacy}", + "followers_url": "https://api.github.com/users/TheRustifyer/followers", + "following_url": "https://api.github.com/users/TheRustifyer/following{/other_user}", + "gists_url": "https://api.github.com/users/TheRustifyer/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/TheRustifyer", + "id": 68871459, + "login": "TheRustifyer", + "node_id": "MDQ6VXNlcjY4ODcxNDU5", + "organizations_url": "https://api.github.com/users/TheRustifyer/orgs", + "received_events_url": "https://api.github.com/users/TheRustifyer/received_events", + "repos_url": "https://api.github.com/users/TheRustifyer/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/TheRustifyer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/TheRustifyer/subscriptions", + "type": "User", + "url": "https://api.github.com/users/TheRustifyer", + "user_view_type": "public" + } + }, + "issue": { + "active_lock_reason": null, + "assignee": { + "avatar_url": "https://avatars.githubusercontent.com/u/68871459?v=4", + "events_url": "https://api.github.com/users/TheRustifyer/events{/privacy}", + "followers_url": "https://api.github.com/users/TheRustifyer/followers", + "following_url": "https://api.github.com/users/TheRustifyer/following{/other_user}", + "gists_url": "https://api.github.com/users/TheRustifyer/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/TheRustifyer", + "id": 68871459, + "login": "TheRustifyer", + "node_id": "MDQ6VXNlcjY4ODcxNDU5", + "organizations_url": "https://api.github.com/users/TheRustifyer/orgs", + "received_events_url": "https://api.github.com/users/TheRustifyer/received_events", + "repos_url": "https://api.github.com/users/TheRustifyer/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/TheRustifyer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/TheRustifyer/subscriptions", + "type": "User", + "url": "https://api.github.com/users/TheRustifyer", + "user_view_type": "public" }, - "repository": { - "name": "app-summoners-sync", - "owner": { - "login": "zerodaycode" + "assignees": [ + { + "avatar_url": "https://avatars.githubusercontent.com/u/68871459?v=4", + "events_url": "https://api.github.com/users/TheRustifyer/events{/privacy}", + "followers_url": "https://api.github.com/users/TheRustifyer/followers", + "following_url": "https://api.github.com/users/TheRustifyer/following{/other_user}", + "gists_url": "https://api.github.com/users/TheRustifyer/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/TheRustifyer", + "id": 68871459, + "login": "TheRustifyer", + "node_id": "MDQ6VXNlcjY4ODcxNDU5", + "organizations_url": "https://api.github.com/users/TheRustifyer/orgs", + "received_events_url": "https://api.github.com/users/TheRustifyer/received_events", + "repos_url": "https://api.github.com/users/TheRustifyer/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/TheRustifyer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/TheRustifyer/subscriptions", + "type": "User", + "url": "https://api.github.com/users/TheRustifyer", + "user_view_type": "public" + } + ], + "author_association": "MEMBER", + "body": null, + "closed_at": null, + "comments": 9, + "comments_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/issues/4/comments", + "created_at": "2024-12-24T21:15:11Z", + "draft": false, + "events_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/issues/4/events", + "html_url": "https://github.com/zerodaycode/app-summoners-sync/pull/4", + "id": 2758305614, + "labels": [ + { + "color": "96E282", + "default": false, + "description": "", + "id": 7925191365, + "name": "ci", + "node_id": "LA_kwDONduBec8AAAAB2GDSxQ", + "url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/labels/ci" } + ], + "labels_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/issues/4/labels{/name}", + "locked": false, + "milestone": null, + "node_id": "PR_kwDONduBec6GMCkB", + "number": 4, + "performed_via_github_app": null, + "pull_request": { + "diff_url": "https://github.com/zerodaycode/app-summoners-sync/pull/4.diff", + "html_url": "https://github.com/zerodaycode/app-summoners-sync/pull/4", + "merged_at": null, + "patch_url": "https://github.com/zerodaycode/app-summoners-sync/pull/4.patch", + "url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/pulls/4" + }, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/issues/4/reactions" + }, + "repository_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync", + "state": "open", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/issues/4/timeline", + "title": "Initial general CI workflows", + "updated_at": "2024-12-27T10:30:39Z", + "url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/issues/4", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/68871459?v=4", + "events_url": "https://api.github.com/users/TheRustifyer/events{/privacy}", + "followers_url": "https://api.github.com/users/TheRustifyer/followers", + "following_url": "https://api.github.com/users/TheRustifyer/following{/other_user}", + "gists_url": "https://api.github.com/users/TheRustifyer/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/TheRustifyer", + "id": 68871459, + "login": "TheRustifyer", + "node_id": "MDQ6VXNlcjY4ODcxNDU5", + "organizations_url": "https://api.github.com/users/TheRustifyer/orgs", + "received_events_url": "https://api.github.com/users/TheRustifyer/received_events", + "repos_url": "https://api.github.com/users/TheRustifyer/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/TheRustifyer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/TheRustifyer/subscriptions", + "type": "User", + "url": "https://api.github.com/users/TheRustifyer", + "user_view_type": "public" } - } \ No newline at end of file + }, + "organization": { + "avatar_url": "https://avatars.githubusercontent.com/u/72573064?v=4", + "description": "", + "events_url": "https://api.github.com/orgs/zerodaycode/events", + "hooks_url": "https://api.github.com/orgs/zerodaycode/hooks", + "id": 72573064, + "issues_url": "https://api.github.com/orgs/zerodaycode/issues", + "login": "zerodaycode", + "members_url": "https://api.github.com/orgs/zerodaycode/members{/member}", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjcyNTczMDY0", + "public_members_url": "https://api.github.com/orgs/zerodaycode/public_members{/member}", + "repos_url": "https://api.github.com/orgs/zerodaycode/repos", + "url": "https://api.github.com/orgs/zerodaycode" + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/assignees{/user}", + "blobs_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/branches{/branch}", + "clone_url": "https://github.com/zerodaycode/app-summoners-sync.git", + "collaborators_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/comments{/number}", + "commits_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/commits{/sha}", + "compare_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/contents/{+path}", + "contributors_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/contributors", + "created_at": "2024-12-15T00:48:55Z", + "custom_properties": {}, + "default_branch": "develop", + "deployments_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/deployments", + "description": "A general purpose repository for holding the docs, assets, demo vids, configuration scripts and many more!", + "disabled": false, + "downloads_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/downloads", + "events_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/events", + "fork": false, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/forks", + "full_name": "zerodaycode/app-summoners-sync", + "git_commits_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/git/tags{/sha}", + "git_url": "git://github.com/zerodaycode/app-summoners-sync.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/hooks", + "html_url": "https://github.com/zerodaycode/app-summoners-sync", + "id": 903577977, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/issues/events{/number}", + "issues_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/issues{/number}", + "keys_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/keys{/key_id}", + "labels_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/labels{/name}", + "language": "JavaScript", + "languages_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/languages", + "license": null, + "merges_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/merges", + "milestones_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/milestones{/number}", + "mirror_url": null, + "name": "app-summoners-sync", + "node_id": "R_kgDONduBeQ", + "notifications_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/notifications{?since,all,participating}", + "open_issues": 3, + "open_issues_count": 3, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/72573064?v=4", + "events_url": "https://api.github.com/users/zerodaycode/events{/privacy}", + "followers_url": "https://api.github.com/users/zerodaycode/followers", + "following_url": "https://api.github.com/users/zerodaycode/following{/other_user}", + "gists_url": "https://api.github.com/users/zerodaycode/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/zerodaycode", + "id": 72573064, + "login": "zerodaycode", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjcyNTczMDY0", + "organizations_url": "https://api.github.com/users/zerodaycode/orgs", + "received_events_url": "https://api.github.com/users/zerodaycode/received_events", + "repos_url": "https://api.github.com/users/zerodaycode/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/zerodaycode/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/zerodaycode/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/zerodaycode", + "user_view_type": "public" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/pulls{/number}", + "pushed_at": "2024-12-27T10:30:10Z", + "releases_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/releases{/id}", + "size": 30, + "ssh_url": "git@github.com:zerodaycode/app-summoners-sync.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/stargazers", + "statuses_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/subscribers", + "subscription_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/subscription", + "svn_url": "https://github.com/zerodaycode/app-summoners-sync", + "tags_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/tags", + "teams_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/zerodaycode/app-summoners-sync/git/trees{/sha}", + "updated_at": "2024-12-27T10:30:13Z", + "url": "https://api.github.com/repos/zerodaycode/app-summoners-sync", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/68871459?v=4", + "events_url": "https://api.github.com/users/TheRustifyer/events{/privacy}", + "followers_url": "https://api.github.com/users/TheRustifyer/followers", + "following_url": "https://api.github.com/users/TheRustifyer/following{/other_user}", + "gists_url": "https://api.github.com/users/TheRustifyer/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/TheRustifyer", + "id": 68871459, + "login": "TheRustifyer", + "node_id": "MDQ6VXNlcjY4ODcxNDU5", + "organizations_url": "https://api.github.com/users/TheRustifyer/orgs", + "received_events_url": "https://api.github.com/users/TheRustifyer/received_events", + "repos_url": "https://api.github.com/users/TheRustifyer/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/TheRustifyer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/TheRustifyer/subscriptions", + "type": "User", + "url": "https://api.github.com/users/TheRustifyer", + "user_view_type": "public" + } +} \ No newline at end of file diff --git a/actions_scripts/notify_user.js b/actions_scripts/notify_user.js index e21a4a7..c8b0eb0 100644 --- a/actions_scripts/notify_user.js +++ b/actions_scripts/notify_user.js @@ -1,9 +1,9 @@ module.exports = async ({github, context, environment, project, infra}) => { - console.log(`CTX: ${JSON.stringify(context, null, 2)}`); + const localRun = context.payload.act; + const isLocalRun = (localRun !== undefined) ? localRun : false; const actor = context.actor; - console.log(`Actor: ${actor}`) - const username = (actor !== "") ? actor : 'Unknown'; + const username = (actor !== undefined && actor !== "") ? actor : 'Unknown'; const prNumber = context.payload.issue.number; @@ -18,9 +18,9 @@ module.exports = async ({github, context, environment, project, infra}) => { message += `- Infrastructure: \`${infra}\`\n`; } - if (context.payload.act === 'true') { + if (isLocalRun) { console.log(`Action is being runned locally by 'ACT'. - Skipping the notify user on PR, but output would have been: + Skipping the REST request to post a message for notify the user on PR, but output would have been: ${message}`); return { comment_id: 10, message: message } // arbitraty mocked comment number; } else { @@ -35,7 +35,7 @@ module.exports = async ({github, context, environment, project, infra}) => { return { comment_id: comment.data.id, message: message }; } catch (ex) { console.log("Failed to POST the comment on the PR to notify the user due to =[> " + ex + "]"); - return { "comment_id": null }; + return { comment_id: null }; } } } \ No newline at end of file From 686cacf79ca9964e325fac9c0f077102796ff782 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Fri, 27 Dec 2024 13:16:37 +0100 Subject: [PATCH 24/93] ci(refactor): splitting the JS code on the notify-user module to make it more readable --- .github/workflows/deploy-chatbot.yml | 13 ++-- actions_scripts/notify_user.js | 90 +++++++++++++++++----------- 2 files changed, 60 insertions(+), 43 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 7452f8d..6a5e7c9 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -69,11 +69,11 @@ jobs: id: notify-user with: script: | - const script = require('./actions_scripts/notify_user.js') + const environment = `${{ steps.parse-command.outputs.environment }}`; + const project = `${{ steps.parse-command.outputs.project }}`; + const infra = `${{ steps.parse-command.outputs.infra }}`; - const environment = `${{ steps.parse-command.outputs.result.environment }}`; - const project = `${{ steps.parse-command.outputs.result.project }}`; - const infra = `${{ steps.parse-command.outputs.result.infra }}`; + const script = require('./actions_scripts/notify_user.js') return await script({github, context, environment, project, infra}) @@ -149,14 +149,11 @@ jobs: with: script: | const workflowLocalRun = `${{ github.event.act }}` === 'true'; - console.log("Is local run: " + workflowLocalRun); - const commentOnPr = JSON.parse(`${{ steps.notify-user.outputs.result }}`); + const commentOnPr = ${{ steps.notify-user.outputs.result }}; const commentId = commentOnPr.comment_id; - console.log(`Updating comment with id ${commentId} for workflow status`); const workflowDetails = ${{ steps.trigger-deployment-workflow.outputs.result }}; - console.log(`Trigger deployment status: ${JSON.stringify(workflowDetails, null, 2)}`); const owner = `${{ github.event.repository.owner.login }}`; const project = `${{ steps.parse-command.outputs.project }}`; diff --git a/actions_scripts/notify_user.js b/actions_scripts/notify_user.js index c8b0eb0..842d057 100644 --- a/actions_scripts/notify_user.js +++ b/actions_scripts/notify_user.js @@ -1,41 +1,61 @@ module.exports = async ({github, context, environment, project, infra}) => { - const localRun = context.payload.act; - const isLocalRun = (localRun !== undefined) ? localRun : false; + const isLocalRun = ciLocalRun(context); - const actor = context.actor; - const username = (actor !== undefined && actor !== "") ? actor : 'Unknown'; + const username = getUsername(context); + const prNumber = context.payload.issue.number; + const message = generatePrCommentMsg(username, environment, project, infra); - const prNumber = context.payload.issue.number; - - let message = `🚀 Deployment action request received from user: ${username}\n`; - if (project) { - message += `- Project: \`${project}\`\n`; - } - if (environment) { - message += `- Environment: \`${environment}\`\n`; - } - if (infra) { - message += `- Infrastructure: \`${infra}\`\n`; + if (isLocalRun) { + logMessageOnLocalEnv(message); + return { comment_id: 10, message: message } // arbitraty mocked comment number; + } else { + try { + const comment = createPrComment(github, context, prNumber, message); + return { comment_id: comment.data.id, message: message }; + } catch (ex) { + console.log("Failed to POST the comment on the PR to notify the user due to =[> " + ex + "]"); + return { comment_id: null }; } + } +} - if (isLocalRun) { - console.log(`Action is being runned locally by 'ACT'. - Skipping the REST request to post a message for notify the user on PR, but output would have been: - ${message}`); - return { comment_id: 10, message: message } // arbitraty mocked comment number; - } else { - let comment = {}; - try { - comment = await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - body: message, - }); - return { comment_id: comment.data.id, message: message }; - } catch (ex) { - console.log("Failed to POST the comment on the PR to notify the user due to =[> " + ex + "]"); - return { comment_id: null }; - } - } +function ciLocalRun(context) { + const localRun = context.payload.act; + return(localRun !== undefined) ? localRun : false; +} + +function getUsername(context) { + const actor = context.actor; + return (actor !== undefined && actor !== "") ? actor : 'Unknown'; + // TODO: throw ex when undefined or non valid actor +} + +function generatePrCommentMsg(username, environment, project, infra) { + let message = `🚀 Deployment action request received from user: ${username}\n`; + if (project) { + message += `- Project: \`${project}\`\n`; + } + if (environment) { + message += `- Environment: \`${environment}\`\n`; + } + if (infra) { + message += `- Infrastructure: \`${infra}\`\n`; + } + + return message; +} + +async function createPrComment(github, context, prNumber, message) { + return await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: message, + }); +} + +function logMessageOnLocalEnv(message) { + console.log(`Action is being runned locally by 'ACT'. + Skipping the REST request to post a message for notify the user on PR, but output would have been: + ${message}`); } \ No newline at end of file From 588db6df0326ef34c1b20568af466075173f2579 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Fri, 27 Dec 2024 13:22:10 +0100 Subject: [PATCH 25/93] ci(fix): missing await on createComment fn --- actions_scripts/notify_user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions_scripts/notify_user.js b/actions_scripts/notify_user.js index 842d057..f062b1f 100644 --- a/actions_scripts/notify_user.js +++ b/actions_scripts/notify_user.js @@ -10,7 +10,7 @@ module.exports = async ({github, context, environment, project, infra}) => { return { comment_id: 10, message: message } // arbitraty mocked comment number; } else { try { - const comment = createPrComment(github, context, prNumber, message); + const comment = await createPrComment(github, context, prNumber, message); return { comment_id: comment.data.id, message: message }; } catch (ex) { console.log("Failed to POST the comment on the PR to notify the user due to =[> " + ex + "]"); From 8652621209bd92c365ba308035b6e6a61949aff3 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Fri, 27 Dec 2024 16:52:11 +0100 Subject: [PATCH 26/93] ci: converting the new JS script to an ES module. Added local type-safety checks --- .github/workflows/deploy-chatbot.yml | 9 +- .gitignore | 2 + actions_scripts/notify_user.js | 78 ++++- actions_scripts/package.json | 3 + package-lock.json | 432 +++++++++++++++++++++++++++ package.json | 5 + 6 files changed, 507 insertions(+), 22 deletions(-) create mode 100644 actions_scripts/package.json create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 6a5e7c9..7d22cd4 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -73,13 +73,8 @@ jobs: const project = `${{ steps.parse-command.outputs.project }}`; const infra = `${{ steps.parse-command.outputs.infra }}`; - const script = require('./actions_scripts/notify_user.js') - - return await script({github, context, environment, project, infra}) - - # TODO: from here, isolate them in independent workflows - # and just call them depending on the input by having just - # a simple and unique trigger deployment + const { default: notifyUser } = await import('${{ github.workspace }}/actions_scripts/notify_user.js') + return await notifyUser({github, context, environment, project, infra}) - name: Trigger Deployment Workflow uses: actions/github-script@v7 diff --git a/.gitignore b/.gitignore index 2751a9c..723ef1d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ .nvim/ .idea/ + +node_modules/ \ No newline at end of file diff --git a/actions_scripts/notify_user.js b/actions_scripts/notify_user.js index f062b1f..2bc1188 100644 --- a/actions_scripts/notify_user.js +++ b/actions_scripts/notify_user.js @@ -1,4 +1,15 @@ -module.exports = async ({github, context, environment, project, infra}) => { +// Main function to notify the user about deployment actions. +/** + * Notify the user about the deployment action. + * @param {Object} options - The options for the notification. + * @param {Object} options.github - GitHub API client provided by actions/github-script. + * @param {Object} options.context - Context object from GitHub Actions, containing payload and environment details. + * @param {string} options.environment - Deployment environment (e.g., pre, prod). + * @param {string} options.project - Project name associated with the deployment. + * @param {string} options.infra - Infrastructure type (e.g., postgres, redis). + * @returns {Object} - An object containing the comment ID and the message content. + */ +export default async ({ github, context, environment, project, infra }) => { const isLocalRun = ciLocalRun(context); const username = getUsername(context); @@ -7,44 +18,76 @@ module.exports = async ({github, context, environment, project, infra}) => { if (isLocalRun) { logMessageOnLocalEnv(message); - return { comment_id: 10, message: message } // arbitraty mocked comment number; + // Return a mock comment ID for local testing purposes. + return { comment_id: 1010101010, message: message }; } else { try { const comment = await createPrComment(github, context, prNumber, message); return { comment_id: comment.data.id, message: message }; } catch (ex) { - console.log("Failed to POST the comment on the PR to notify the user due to =[> " + ex + "]"); + console.log("Failed to POST the comment on the PR to notify the user due to =[> " + ex + "]"); return { comment_id: null }; } } -} +}; +// Helper function to determine if the workflow is running locally. +/** + * Check if the current run is a local run (e.g., with ACT). + * @param {Object} context - GitHub Actions context object. + * @returns {boolean} - True if running locally, false otherwise. + */ function ciLocalRun(context) { const localRun = context.payload.act; - return(localRun !== undefined) ? localRun : false; + return (localRun !== undefined) ? localRun : false; } +// Helper function to retrieve the username of the actor triggering the workflow. +/** + * Get the username of the actor from the context. + * @param {Object} context - GitHub Actions context object. + * @returns {string} - The username of the actor. + * @throws {Error} - if the parsed actor text is non validdfd + */ function getUsername(context) { const actor = context.actor; - return (actor !== undefined && actor !== "") ? actor : 'Unknown'; - // TODO: throw ex when undefined or non valid actor + if (actor !== undefined && actor !== "") + return actor; + else + throw new Error("Unable to determine the actor (user) that triggered this deploy. Leaving..."); } +// Helper function to generate the PR comment message. +/** + * Generate the content of the PR comment to notify the user. + * @param {string} username - Username of the actor triggering the workflow. + * @param {string} environment - Deployment environment (e.g., pre, pre-pro, pro). + * @param {string} project - Project name associated with the deployment. + * @param {string} infra - Infrastructure entity (e.g., postgres, redis). + * @returns {string} - The formatted message to be posted on the PR. + */ function generatePrCommentMsg(username, environment, project, infra) { let message = `🚀 Deployment action request received from user: ${username}\n`; - if (project) { + + if (project) message += `- Project: \`${project}\`\n`; - } - if (environment) { + if (environment) message += `- Environment: \`${environment}\`\n`; - } - if (infra) { + if (infra) message += `- Infrastructure: \`${infra}\`\n`; - } return message; } +// Helper function to create a PR comment via the GitHub API. +/** + * Post a comment on the PR to notify the user. + * @param {Object} github - GitHub API client. + * @param {Object} context - GitHub Actions context object. + * @param {number} prNumber - Pull request number. + * @param {string} message - Message content to be posted. + * @returns {Object} - The response object from the GitHub API. + */ async function createPrComment(github, context, prNumber, message) { return await github.rest.issues.createComment({ owner: context.repo.owner, @@ -54,8 +97,13 @@ async function createPrComment(github, context, prNumber, message) { }); } +// Helper function to log the PR comment message in a local environment. +/** + * Log the message locally for debugging when running with ACT. + * @param {string} message - Message content to be logged. + */ function logMessageOnLocalEnv(message) { console.log(`Action is being runned locally by 'ACT'. - Skipping the REST request to post a message for notify the user on PR, but output would have been: + Skipping the REST request to post a message for notifying the user on PR, but the output would have been: ${message}`); -} \ No newline at end of file +} diff --git a/actions_scripts/package.json b/actions_scripts/package.json new file mode 100644 index 0000000..96ae6e5 --- /dev/null +++ b/actions_scripts/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..b6f46fd --- /dev/null +++ b/package-lock.json @@ -0,0 +1,432 @@ +{ + "name": "app-summoners-sync", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "@types/github-script": "github:actions/github-script" + } + }, + "node_modules/@actions/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz", + "integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@actions/exec": "^1.1.1", + "@actions/http-client": "^2.0.1" + } + }, + "node_modules/@actions/exec": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz", + "integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@actions/io": "^1.0.1" + } + }, + "node_modules/@actions/github": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-6.0.0.tgz", + "integrity": "sha512-alScpSVnYmjNEXboZjarjukQEzgCRmjMv6Xj47fsdnqGS73bjJNDpiiXmp8jr0UZLdUB6d9jW63IcmddUP+l0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@actions/http-client": "^2.2.0", + "@octokit/core": "^5.0.1", + "@octokit/plugin-paginate-rest": "^9.0.0", + "@octokit/plugin-rest-endpoint-methods": "^10.0.0" + } + }, + "node_modules/@actions/glob": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.4.0.tgz", + "integrity": "sha512-+eKIGFhsFa4EBwaf/GMyzCdWrXWymGXfFmZU3FHQvYS8mPcHtTtZONbkcqqUMzw9mJ/pImEBFET1JNifhqGsAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@actions/core": "^1.9.1", + "minimatch": "^3.0.4" + } + }, + "node_modules/@actions/http-client": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.3.tgz", + "integrity": "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tunnel": "^0.0.6", + "undici": "^5.25.4" + } + }, + "node_modules/@actions/io": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz", + "integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz", + "integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.3.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.5.tgz", + "integrity": "sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.0.tgz", + "integrity": "sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^8.3.0", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz", + "integrity": "sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^12.6.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^20.0.0" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", + "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz", + "integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^12.6.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^20.0.0" + } + }, + "node_modules/@octokit/plugin-retry": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-6.1.0.tgz", + "integrity": "sha512-WrO3bvq4E1Xh1r2mT9w6SDFg01gFmP81nIG77+p/MqW1JeXXgL++6umim3t6x0Zj5pZm3rXAN+0HEjmmdhIRig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^13.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/request": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.0.tgz", + "integrity": "sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^9.0.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.0.tgz", + "integrity": "sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/types": { + "version": "13.6.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.2.tgz", + "integrity": "sha512-WpbZfZUcZU77DrSW4wbsSgTPfKcp286q3ItaIgvSbBpZJlu6mnYXAkjZz6LVZPXkEvLIM8McanyZejKTYUHipA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/@types/github-script": { + "name": "github-script", + "version": "7.0.1", + "resolved": "git+ssh://git@github.com/actions/github-script.git#4020e461acd7a80762cdfff123a1fde368246fa4", + "dev": true, + "license": "MIT", + "dependencies": { + "@actions/core": "^1.10.1", + "@actions/exec": "^1.1.1", + "@actions/github": "^6.0.0", + "@actions/glob": "^0.4.0", + "@actions/io": "^1.1.3", + "@octokit/core": "^5.0.1", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-retry": "^6.0.1", + "@types/node": "^20.9.0" + }, + "engines": { + "node": ">=20.0.0 <21.0.0" + } + }, + "node_modules/@types/node": { + "version": "20.17.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz", + "integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/undici": { + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/universal-user-agent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..fb11d56 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "@types/github-script": "github:actions/github-script" + } +} From 66478accaea05f61a019d1d79ed8d06bfeb47529 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Fri, 27 Dec 2024 17:28:21 +0100 Subject: [PATCH 27/93] ci: refactoring common helper functions into their own modules --- actions_scripts/helpers.js | 28 ++++++++++++++++++++++++++ actions_scripts/notify_user.js | 30 +++------------------------- actions_scripts/package.json | 3 --- actions_scripts/update_pr_comment.js | 0 package.json | 1 + 5 files changed, 32 insertions(+), 30 deletions(-) create mode 100644 actions_scripts/helpers.js delete mode 100644 actions_scripts/package.json create mode 100644 actions_scripts/update_pr_comment.js diff --git a/actions_scripts/helpers.js b/actions_scripts/helpers.js new file mode 100644 index 0000000..edad459 --- /dev/null +++ b/actions_scripts/helpers.js @@ -0,0 +1,28 @@ +// Contains helper functions made to be reusable across the JS scripts +// of the notifications + +// Helper function to determine if the workflow is running locally. +/** + * Check if the current run is a local run (e.g., with ACT). + * @param {Object} context - GitHub Actions context object. + * @returns {boolean} - True if running locally, false otherwise. + */ +export function ciLocalRun(context) { + const localRun = context.payload.act; + return (localRun !== undefined) ? localRun : false; +} + +// Helper function to retrieve the username of the actor triggering the workflow. +/** + * Get the username of the actor from the context. + * @param {Object} context - GitHub Actions context object. + * @returns {string} - The username of the actor. + * @throws {Error} - if the parsed actor text is non validdfd + */ +export function extractUsername(context) { + const actor = context.actor; + if (actor !== undefined && actor !== "") + return actor; + else + throw new Error("Unable to determine the actor (user) that triggered this deploy. Leaving..."); +} \ No newline at end of file diff --git a/actions_scripts/notify_user.js b/actions_scripts/notify_user.js index 2bc1188..d50d6a5 100644 --- a/actions_scripts/notify_user.js +++ b/actions_scripts/notify_user.js @@ -1,3 +1,5 @@ +import { ciLocalRun, extractUsername } from "./helpers.js"; + // Main function to notify the user about deployment actions. /** * Notify the user about the deployment action. @@ -12,7 +14,7 @@ export default async ({ github, context, environment, project, infra }) => { const isLocalRun = ciLocalRun(context); - const username = getUsername(context); + const username = extractUsername(context); const prNumber = context.payload.issue.number; const message = generatePrCommentMsg(username, environment, project, infra); @@ -31,32 +33,6 @@ export default async ({ github, context, environment, project, infra }) => { } }; -// Helper function to determine if the workflow is running locally. -/** - * Check if the current run is a local run (e.g., with ACT). - * @param {Object} context - GitHub Actions context object. - * @returns {boolean} - True if running locally, false otherwise. - */ -function ciLocalRun(context) { - const localRun = context.payload.act; - return (localRun !== undefined) ? localRun : false; -} - -// Helper function to retrieve the username of the actor triggering the workflow. -/** - * Get the username of the actor from the context. - * @param {Object} context - GitHub Actions context object. - * @returns {string} - The username of the actor. - * @throws {Error} - if the parsed actor text is non validdfd - */ -function getUsername(context) { - const actor = context.actor; - if (actor !== undefined && actor !== "") - return actor; - else - throw new Error("Unable to determine the actor (user) that triggered this deploy. Leaving..."); -} - // Helper function to generate the PR comment message. /** * Generate the content of the PR comment to notify the user. diff --git a/actions_scripts/package.json b/actions_scripts/package.json deleted file mode 100644 index 96ae6e5..0000000 --- a/actions_scripts/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} \ No newline at end of file diff --git a/actions_scripts/update_pr_comment.js b/actions_scripts/update_pr_comment.js new file mode 100644 index 0000000..e69de29 diff --git a/package.json b/package.json index fb11d56..e658149 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,5 @@ { + "type": "module", "devDependencies": { "@types/github-script": "github:actions/github-script" } From a489b740b403e7563f986fe6eb3521fa30ae16bc Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Fri, 27 Dec 2024 22:08:59 +0100 Subject: [PATCH 28/93] ci: refactoring the parse-command step --- .github/workflows/deploy-chatbot.yml | 53 ++++----------------- actions_scripts/notify_user.js | 1 - actions_scripts/parse_deployment_command.js | 48 +++++++++++++++++++ actions_scripts/update_pr_comment.js | 0 4 files changed, 57 insertions(+), 45 deletions(-) create mode 100644 actions_scripts/parse_deployment_command.js delete mode 100644 actions_scripts/update_pr_comment.js diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 7d22cd4..2ba7f28 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -9,50 +9,17 @@ jobs: handle-deployment-on-pr-comment: runs-on: ubuntu-latest - steps: + steps: + - uses: actions/checkout@v4 + - name: Parse Deployment Command + uses: actions/github-script@v7 id: parse-command - run: | - WORKFLOW_LOCAL_RUN="${{ !github.event.act }}" - COMMENT_BODY="${{ github.event.comment.body }}" - if [[ WORKFLOW_LOCAL_RUN ]]; then - echo "Setting the command as a mock since it's running locally with ACT" - COMMENT_BODY='/deploy --environment pre --project ag-summoners-sync' - fi - - echo "Comment received: $COMMENT_BODY" - - # Initialize variables - ENVIRONMENT="" - PROJECT="" - INFRA="" - - # Parse environment - if [[ "$COMMENT_BODY" =~ --environment[[:space:]]+([a-zA-Z0-9_-]+) ]]; then - ENVIRONMENT="${BASH_REMATCH[1]}" - echo "Environment: $ENVIRONMENT" - fi - - # Parse project - if [[ "$COMMENT_BODY" =~ --project[[:space:]]+([a-zA-Z0-9_-]+) ]]; then - PROJECT="${BASH_REMATCH[1]}" - echo "Project: $PROJECT" - else - echo "No environment specified. Aborting workflow." - exit 1 # Aborts the workflow # TODO: pass it as an output to the user notifier step - fi - - # Parse infra - if [[ "$COMMENT_BODY" =~ --infra[[:space:]]+([a-zA-Z0-9_-]+) ]]; then - INFRA="${BASH_REMATCH[1]}" - echo "Infra: $INFRA" - fi - - # Output parsed values - echo "environment=$ENVIRONMENT" >> $GITHUB_OUTPUT - echo "project=$PROJECT" >> $GITHUB_OUTPUT - echo "infra=$INFRA" >> $GITHUB_OUTPUT - + with: + script: | + const { default: parseDeployCommand } = await import('${{ github.workspace }}/actions_scripts/parse_deployment_command.js') + parseDeployCommand({context, core}) + - name: Get GH Zero Day Code APP token if: ${{ !github.event.act }} uses: actions/create-github-app-token@v1 @@ -62,8 +29,6 @@ jobs: private-key: ${{ secrets.ZDC_AUTH_PRIVATE_KEY }} owner: ${{ github.repository_owner }} - - uses: actions/checkout@v4 - - name: Notify the user uses: actions/github-script@v7 id: notify-user diff --git a/actions_scripts/notify_user.js b/actions_scripts/notify_user.js index d50d6a5..3290e73 100644 --- a/actions_scripts/notify_user.js +++ b/actions_scripts/notify_user.js @@ -1,6 +1,5 @@ import { ciLocalRun, extractUsername } from "./helpers.js"; -// Main function to notify the user about deployment actions. /** * Notify the user about the deployment action. * @param {Object} options - The options for the notification. diff --git a/actions_scripts/parse_deployment_command.js b/actions_scripts/parse_deployment_command.js new file mode 100644 index 0000000..5cb396f --- /dev/null +++ b/actions_scripts/parse_deployment_command.js @@ -0,0 +1,48 @@ +/** + * Parse the input command of the user in the PR. + * @param {Object} options - The options for the notification. + * @param {Object} options.context - Context object from GitHub Actions, containing payload and environment details. + * @param {Object} options.core module for interacting with GitHub Actions workflow commands and outputs. +*/ +export default ({context, core}) => { + const localRun = !context.payload.act; + let commentBody = context.payload.comment?.body || ''; + + if (localRun) + console.log("Setting the command as a mock since it's running locally with ACT"); + console.log(`Comment received: ${commentBody}`); + + // Initialize variables + let environment = ''; + let project = ''; + let infra = ''; + + // Parse environment + const environmentMatch = commentBody.match(/--environment\s+([a-zA-Z0-9_-]+)/); + if (environmentMatch) { + environment = environmentMatch[1]; + console.log(`Environment: ${environment}`); + } + + // Parse project + const projectMatch = commentBody.match(/--project\s+([a-zA-Z0-9_-]+)/); + if (projectMatch) { + project = projectMatch[1]; + console.log(`Project: ${project}`); + } else { + core.setFailed("No project specified. Aborting workflow."); + return; + } + + // Parse infra + const infraMatch = commentBody.match(/--infra\s+([a-zA-Z0-9_-]+)/); + if (infraMatch) { + infra = infraMatch[1]; + console.log(`Infra: ${infra}`); + } + + // Set outputs + core.setOutput("environment", environment); + core.setOutput("project", project); + core.setOutput("infra", infra); +}; \ No newline at end of file diff --git a/actions_scripts/update_pr_comment.js b/actions_scripts/update_pr_comment.js deleted file mode 100644 index e69de29..0000000 From abadcb07920fcf778198d9b48ec881cda3fd0e64 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Sat, 28 Dec 2024 12:02:53 +0100 Subject: [PATCH 29/93] ci: refactoring the update-pr-comment-step from inlined on yml to JS (ES) module --- .github/workflows/deploy-chatbot.yml | 50 +++++++++------------------- actions_scripts/helpers.js | 16 ++++++++- actions_scripts/update_pr_comment.js | 34 +++++++++++++++++++ 3 files changed, 64 insertions(+), 36 deletions(-) create mode 100644 actions_scripts/update_pr_comment.js diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 2ba7f28..f2c1007 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -14,7 +14,7 @@ jobs: - name: Parse Deployment Command uses: actions/github-script@v7 - id: parse-command + id: parse_command with: script: | const { default: parseDeployCommand } = await import('${{ github.workspace }}/actions_scripts/parse_deployment_command.js') @@ -31,24 +31,24 @@ jobs: - name: Notify the user uses: actions/github-script@v7 - id: notify-user + id: notify_user with: script: | - const environment = `${{ steps.parse-command.outputs.environment }}`; - const project = `${{ steps.parse-command.outputs.project }}`; - const infra = `${{ steps.parse-command.outputs.infra }}`; + const environment = `${{ steps.parse_command.outputs.environment }}`; + const project = `${{ steps.parse_command.outputs.project }}`; + const infra = `${{ steps.parse_command.outputs.infra }}`; const { default: notifyUser } = await import('${{ github.workspace }}/actions_scripts/notify_user.js') return await notifyUser({github, context, environment, project, infra}) - name: Trigger Deployment Workflow uses: actions/github-script@v7 - id: trigger-deployment-workflow + id: trigger_deployment_workflow with: github-token: ${{ steps.zdc-auth-app-token.outputs.token || github.token }} script: | - const environment = `${{ steps.parse-command.outputs.environment }}`; - const project = `${{ steps.parse-command.outputs.project }}`; + const environment = `${{ steps.parse_command.outputs.environment }}`; + const project = `${{ steps.parse_command.outputs.project }}`; const workflowId = `deploy-${environment}.yml`; let result = ""; @@ -77,14 +77,14 @@ jobs: }; - name: Deploy Infra - if: steps.parse-command.outputs.infra != '' + if: steps.parse_command.outputs.infra != '' uses: appleboy/ssh-action@v1.2.0 with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USERNAME }} key: ${{ secrets.SSH_KEY }} script: | - case "${{ steps.parse-command.outputs.infra }}" in + case "${{ steps.parse_command.outputs.infra }}" in postgres) echo "Deploying Postgres..." docker run -d --name postgres --restart always -e POSTGRES_PASSWORD=mysecretpassword postgres @@ -99,7 +99,7 @@ jobs: docker run -d --name redis --restart always redis ;; *) - echo "Unknown infra: ${{ steps.parse-command.outputs.infra }}" + echo "Unknown infra: ${{ steps.parse_command.outputs.infra }}" ;; esac @@ -108,29 +108,9 @@ jobs: id: update-comment-with-deployment-status with: script: | - const workflowLocalRun = `${{ github.event.act }}` === 'true'; + const steps = ${{ toJSON(steps) }}; - const commentOnPr = ${{ steps.notify-user.outputs.result }}; - const commentId = commentOnPr.comment_id; + const { default: updatePrComment } = + await import('${{ github.workspace }}/actions_scripts/update_pr_comment.js') - const workflowDetails = ${{ steps.trigger-deployment-workflow.outputs.result }}; - - const owner = `${{ github.event.repository.owner.login }}`; - const project = `${{ steps.parse-command.outputs.project }}`; - const runUrl = `https://github.com/${owner}/${project}/actions`; - - const statusIcon = workflowDetails.status === 'OK' ? '✅' : '❌'; - const statusMsg = workflowDetails.details; - - const previousMsgData = commentOnPr.message; - const message = `${previousMsgData}\n${statusIcon} Deployment ${statusMsg}. [View Workflow](${runUrl})`; - console.log(message); - - if (!workflowLocalRun) { - await github.rest.issues.updateComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: commentId, - body: message, - }); - } + await updatePrComment(github, context, steps) \ No newline at end of file diff --git a/actions_scripts/helpers.js b/actions_scripts/helpers.js index edad459..a2d155d 100644 --- a/actions_scripts/helpers.js +++ b/actions_scripts/helpers.js @@ -17,7 +17,7 @@ export function ciLocalRun(context) { * Get the username of the actor from the context. * @param {Object} context - GitHub Actions context object. * @returns {string} - The username of the actor. - * @throws {Error} - if the parsed actor text is non validdfd + * @throws {Error} - if the parsed actor text is non valid */ export function extractUsername(context) { const actor = context.actor; @@ -25,4 +25,18 @@ export function extractUsername(context) { return actor; else throw new Error("Unable to determine the actor (user) that triggered this deploy. Leaving..."); +} + +// Helper function to retrieve the owner of the repository in which the action has been triggered. +/** + * Get the username of the actor from the context. + * @param {Object} context - GitHub Actions context object. + * @returns {string} - The owner of the repository. + */ +export function getRepoOwner(context) { + const owner = context.payload.organization.login; + if (owner !== undefined && owner !== "") + return owner; + else + throw new Error("Unable to parse the owner name of the repository. Leaving..."); } \ No newline at end of file diff --git a/actions_scripts/update_pr_comment.js b/actions_scripts/update_pr_comment.js new file mode 100644 index 0000000..2c8f7e1 --- /dev/null +++ b/actions_scripts/update_pr_comment.js @@ -0,0 +1,34 @@ +import { ciLocalRun, getRepoOwner } from "./helpers.js"; + +/** + * Takes the previous posted message as a comment on the PR that triggered + * the deploy command in order to add it the status of the deployment to + * that message + */ +export default async (github, context, steps) => { + const isLocalRun = ciLocalRun(context); + + const repoOwner = getRepoOwner(context); + const targetRepo = steps.parse_command.outputs.project; + + const previousPrComment = JSON.parse(steps.notify_user.outputs.result); + const commentId = previousPrComment.comment_id; + const runUrl = `https://github.com/${repoOwner}/${targetRepo}/actions`; + + const workflowExecution = JSON.parse(steps.trigger_deployment_workflow.outputs.result); + const statusIcon = workflowExecution.status === 'OK' ? '✅' : '❌'; + const statusMsg = workflowExecution.details; + + const previousMsgData = previousPrComment.message; + const message = `${previousMsgData}\n${statusIcon} Deployment ${statusMsg}. [View Workflow](${runUrl})`; + console.log(`Message: ${message}`); + + if (!isLocalRun) { + await github.rest.issues.updateComment({ + owner: repoOwner, + repo: context.repo.repo, + comment_id: commentId, + body: message, + }); + } +} \ No newline at end of file From b5142fb19c9daa8494f2b0fe4ec3c952b4fc09d0 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Sat, 28 Dec 2024 12:06:47 +0100 Subject: [PATCH 30/93] ci: refactoring the update-pr-comment-step from inlined on yml to JS (ES) module --- .github/workflows/deploy-chatbot.yml | 6 ++++-- actions_scripts/notify_user.js | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index f2c1007..8eb84ec 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -38,8 +38,10 @@ jobs: const project = `${{ steps.parse_command.outputs.project }}`; const infra = `${{ steps.parse_command.outputs.infra }}`; - const { default: notifyUser } = await import('${{ github.workspace }}/actions_scripts/notify_user.js') - return await notifyUser({github, context, environment, project, infra}) + const { default: notifyUser } = + await import('${{ github.workspace }}/actions_scripts/notify_user.js') + + return await notifyUser(github, context, steps) - name: Trigger Deployment Workflow uses: actions/github-script@v7 diff --git a/actions_scripts/notify_user.js b/actions_scripts/notify_user.js index 3290e73..c399b17 100644 --- a/actions_scripts/notify_user.js +++ b/actions_scripts/notify_user.js @@ -10,7 +10,9 @@ import { ciLocalRun, extractUsername } from "./helpers.js"; * @param {string} options.infra - Infrastructure type (e.g., postgres, redis). * @returns {Object} - An object containing the comment ID and the message content. */ -export default async ({ github, context, environment, project, infra }) => { +export default async (options) => { + const { github, context, environment, project, infra } = options; + const isLocalRun = ciLocalRun(context); const username = extractUsername(context); From 3c2483aca563d377d89ab395de12ec89881727b9 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Sat, 28 Dec 2024 12:11:03 +0100 Subject: [PATCH 31/93] ci: minor code fmt and refactors --- .github/workflows/deploy-chatbot.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 8eb84ec..bb851b9 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -17,8 +17,10 @@ jobs: id: parse_command with: script: | - const { default: parseDeployCommand } = await import('${{ github.workspace }}/actions_scripts/parse_deployment_command.js') - parseDeployCommand({context, core}) + const { default: parseDeployCommand } = + await import('${{ github.workspace }}/actions_scripts/parse_deployment_command.js'); + + parseDeployCommand({context, core}); - name: Get GH Zero Day Code APP token if: ${{ !github.event.act }} @@ -39,9 +41,9 @@ jobs: const infra = `${{ steps.parse_command.outputs.infra }}`; const { default: notifyUser } = - await import('${{ github.workspace }}/actions_scripts/notify_user.js') + await import('${{ github.workspace }}/actions_scripts/notify_user.js'); - return await notifyUser(github, context, steps) + return await notifyUser({github, context, environment, project, infra}); - name: Trigger Deployment Workflow uses: actions/github-script@v7 @@ -113,6 +115,6 @@ jobs: const steps = ${{ toJSON(steps) }}; const { default: updatePrComment } = - await import('${{ github.workspace }}/actions_scripts/update_pr_comment.js') + await import('${{ github.workspace }}/actions_scripts/update_pr_comment.js'); - await updatePrComment(github, context, steps) \ No newline at end of file + await updatePrComment(github, context, steps); \ No newline at end of file From dffea0726dc06ed0339fea5cec03b3048d02e42b Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Sat, 28 Dec 2024 12:23:52 +0100 Subject: [PATCH 32/93] ci: core.setFailed on the catch of REST requests --- .github/workflows/deploy-chatbot.yml | 2 +- actions_scripts/notify_user.js | 12 ++++++------ actions_scripts/update_pr_comment.js | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index bb851b9..61d75f7 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -43,7 +43,7 @@ jobs: const { default: notifyUser } = await import('${{ github.workspace }}/actions_scripts/notify_user.js'); - return await notifyUser({github, context, environment, project, infra}); + return await notifyUser({github, context, core, environment, project, infra}); - name: Trigger Deployment Workflow uses: actions/github-script@v7 diff --git a/actions_scripts/notify_user.js b/actions_scripts/notify_user.js index c399b17..3d4c3b9 100644 --- a/actions_scripts/notify_user.js +++ b/actions_scripts/notify_user.js @@ -5,14 +5,15 @@ import { ciLocalRun, extractUsername } from "./helpers.js"; * @param {Object} options - The options for the notification. * @param {Object} options.github - GitHub API client provided by actions/github-script. * @param {Object} options.context - Context object from GitHub Actions, containing payload and environment details. + * @param {Object} options.core - Core object from GitHub Actions, containing actions to perform over the workflow. * @param {string} options.environment - Deployment environment (e.g., pre, prod). * @param {string} options.project - Project name associated with the deployment. * @param {string} options.infra - Infrastructure type (e.g., postgres, redis). * @returns {Object} - An object containing the comment ID and the message content. */ export default async (options) => { - const { github, context, environment, project, infra } = options; - + const { github, context, core, environment, project, infra } = options; + const isLocalRun = ciLocalRun(context); const username = extractUsername(context); @@ -22,14 +23,13 @@ export default async (options) => { if (isLocalRun) { logMessageOnLocalEnv(message); // Return a mock comment ID for local testing purposes. - return { comment_id: 1010101010, message: message }; + return { id: 1010101010, message: message }; } else { try { const comment = await createPrComment(github, context, prNumber, message); - return { comment_id: comment.data.id, message: message }; + return { id: comment.data.id, message: message }; } catch (ex) { - console.log("Failed to POST the comment on the PR to notify the user due to =[> " + ex + "]"); - return { comment_id: null }; + core.setFailed("Failed to POST the comment on the PR to notify the user due to =[> " + ex + "]"); } } }; diff --git a/actions_scripts/update_pr_comment.js b/actions_scripts/update_pr_comment.js index 2c8f7e1..0d2c14d 100644 --- a/actions_scripts/update_pr_comment.js +++ b/actions_scripts/update_pr_comment.js @@ -12,7 +12,7 @@ export default async (github, context, steps) => { const targetRepo = steps.parse_command.outputs.project; const previousPrComment = JSON.parse(steps.notify_user.outputs.result); - const commentId = previousPrComment.comment_id; + const commentId = previousPrComment.id; const runUrl = `https://github.com/${repoOwner}/${targetRepo}/actions`; const workflowExecution = JSON.parse(steps.trigger_deployment_workflow.outputs.result); @@ -27,7 +27,7 @@ export default async (github, context, steps) => { await github.rest.issues.updateComment({ owner: repoOwner, repo: context.repo.repo, - comment_id: commentId, + id: commentId, body: message, }); } From fb0a57c6cefbe663c92f9020acb8a37c18672d72 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Sat, 28 Dec 2024 13:16:13 +0100 Subject: [PATCH 33/93] ci: introducing tests with jest for the actions-scripts. Added a workflow to run them --- .github/workflows/actions-scripts-tests.yml | 32 + actions_scripts/__tests__/notify_user.test.js | 68 + jest.config.js | 8 + package-lock.json | 3918 ++++++++++++++++- package.json | 6 +- 5 files changed, 3856 insertions(+), 176 deletions(-) create mode 100644 .github/workflows/actions-scripts-tests.yml create mode 100644 actions_scripts/__tests__/notify_user.test.js create mode 100644 jest.config.js diff --git a/.github/workflows/actions-scripts-tests.yml b/.github/workflows/actions-scripts-tests.yml new file mode 100644 index 0000000..a2bb31e --- /dev/null +++ b/.github/workflows/actions-scripts-tests.yml @@ -0,0 +1,32 @@ +name: Test Action Scripts + +on: + push: + paths: + - 'actions_scripts/**' # Trigger only when files in this folder are modified + pull_request: + paths: + - 'actions_scripts/**' # Run on PRs affecting the actions_scripts folder + +jobs: + test-and-coverage: + runs-on: ubuntu-latest + + steps: + # Checkout the repository + - name: Checkout code + uses: actions/checkout@v4 + + # Set up Node.js environment + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '23' + + # Install dependencies + - name: Install dependencies + run: npm ci + + # Run tests and collect coverage + - name: Run tests and generate coverage + run: npm test \ No newline at end of file diff --git a/actions_scripts/__tests__/notify_user.test.js b/actions_scripts/__tests__/notify_user.test.js new file mode 100644 index 0000000..efc8bdc --- /dev/null +++ b/actions_scripts/__tests__/notify_user.test.js @@ -0,0 +1,68 @@ +import { jest } from '@jest/globals'; + +const notifyUser = (await import('../notify_user.js')).default + +describe('notifyUser', () => { + it('should create a PR comment when running in a non-local environment', async () => { + // Mock dependencies + const mockGithub = { + rest: { + issues: { + createComment: jest.fn().mockResolvedValue({ data: { id: 12345 } }), + }, + }, + }; + + const mockContextCloud = { + repo: { owner: 'test-owner', repo: 'test-repo' }, + payload: { issue: { number: 42 } }, + actor: 'test-user', + }; + + const environment = 'test-env'; + const project = 'test-project'; + const infra = 'test-infra'; + + // Call the function + const result = await notifyUser({ + github: mockGithub, + context: mockContextCloud, + environment, + project, + infra, + }); + + // Assertions + expect(mockGithub.rest.issues.createComment).toHaveBeenCalledWith({ + owner: 'test-owner', + repo: 'test-repo', + issue_number: 42, + body: expect.stringContaining('🚀 Deployment action request received from user: test-user'), + }); + expect(result).toEqual({ id: 12345, message: expect.any(String) }); + }); + + it('should log a message when running in a local environment', async () => { + const mockContext = { + payload: { act: true, issue: { number: 42 } }, // Simulates a local run + actor: 'test-user', + }; + + const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {}); + + const result = await notifyUser({ + github: {}, + context: mockContext, + environment: 'local-env', + project: 'local-project', + infra: 'local-infra', + }); + + expect(consoleSpy).toHaveBeenCalledWith( + expect.stringContaining('Action is being runned locally by \'ACT\'') + ); + expect(result).toEqual({ id: 1010101010, message: expect.any(String) }); + + consoleSpy.mockRestore(); + }); +}); diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..ee26e9f --- /dev/null +++ b/jest.config.js @@ -0,0 +1,8 @@ +// Base configuration for using 'JEST' as our test suite for this repo 'JS' custom scripts +// that typically we use in our actions + +export default { + transform: {}, // Disable default Babel transform + testEnvironment: 'node', // Default to Node.js environment +}; + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b6f46fd..3e0fb5f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,8 @@ "packages": { "": { "devDependencies": { - "@types/github-script": "github:actions/github-script" + "@types/github-script": "github:actions/github-script", + "jest": "^29.7.0" } }, "node_modules/@actions/core": { @@ -71,307 +72,3154 @@ "dev": true, "license": "MIT" }, - "node_modules/@fastify/busboy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", - "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, "engines": { - "node": ">=14" + "node": ">=6.9.0" } }, - "node_modules/@octokit/auth-token": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", - "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "node_modules/@babel/compat-data": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", + "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", "dev": true, "license": "MIT", "engines": { - "node": ">= 18" + "node": ">=6.9.0" } }, - "node_modules/@octokit/core": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz", - "integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==", + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/auth-token": "^4.0.0", - "@octokit/graphql": "^7.1.0", - "@octokit/request": "^8.3.1", - "@octokit/request-error": "^5.1.0", - "@octokit/types": "^13.0.0", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { - "node": ">= 18" + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "node_modules/@octokit/endpoint": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.5.tgz", - "integrity": "sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==", + "node_modules/@babel/generator": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", + "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/types": "^13.1.0", - "universal-user-agent": "^6.0.0" + "@babel/parser": "^7.26.3", + "@babel/types": "^7.26.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" }, "engines": { - "node": ">= 18" + "node": ">=6.9.0" } }, - "node_modules/@octokit/graphql": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.0.tgz", - "integrity": "sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/request": "^8.3.0", - "@octokit/types": "^13.0.0", - "universal-user-agent": "^6.0.0" + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { - "node": ">= 18" + "node": ">=6.9.0" } }, - "node_modules/@octokit/openapi-types": { - "version": "22.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", - "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz", - "integrity": "sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/types": "^12.6.0" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { - "node": ">= 18" + "node": ">=6.9.0" }, "peerDependencies": { - "@octokit/core": "5" + "@babel/core": "^7.0.0" } }, - "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", - "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==", + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, - "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { - "version": "12.6.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", - "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, "license": "MIT", - "dependencies": { - "@octokit/openapi-types": "^20.0.0" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@octokit/plugin-request-log": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", - "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, "license": "MIT", "engines": { - "node": ">= 18" + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, - "peerDependencies": { - "@octokit/core": "5" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz", - "integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==", + "node_modules/@babel/parser": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/types": "^12.6.0" + "@babel/types": "^7.26.3" + }, + "bin": { + "parser": "bin/babel-parser.js" }, "engines": { - "node": ">= 18" + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { - "@octokit/core": "5" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", - "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==", + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": { - "version": "12.6.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", - "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/openapi-types": "^20.0.0" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@octokit/plugin-retry": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-6.1.0.tgz", - "integrity": "sha512-WrO3bvq4E1Xh1r2mT9w6SDFg01gFmP81nIG77+p/MqW1JeXXgL++6umim3t6x0Zj5pZm3rXAN+0HEjmmdhIRig==", + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^13.0.0", - "bottleneck": "^2.15.3" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": ">= 18" + "node": ">=6.9.0" }, "peerDependencies": { - "@octokit/core": "5" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@octokit/request": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.0.tgz", - "integrity": "sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==", + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/endpoint": "^9.0.1", - "@octokit/request-error": "^5.1.0", - "@octokit/types": "^13.1.0", - "universal-user-agent": "^6.0.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { - "node": ">= 18" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@octokit/request-error": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.0.tgz", - "integrity": "sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==", + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/types": "^13.1.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" + "@babel/helper-plugin-utils": "^7.10.4" }, - "engines": { - "node": ">= 18" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@octokit/types": { - "version": "13.6.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.2.tgz", - "integrity": "sha512-WpbZfZUcZU77DrSW4wbsSgTPfKcp286q3ItaIgvSbBpZJlu6mnYXAkjZz6LVZPXkEvLIM8McanyZejKTYUHipA==", + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/openapi-types": "^22.2.0" + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@types/github-script": { - "name": "github-script", - "version": "7.0.1", - "resolved": "git+ssh://git@github.com/actions/github-script.git#4020e461acd7a80762cdfff123a1fde368246fa4", + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", "dev": true, "license": "MIT", "dependencies": { - "@actions/core": "^1.10.1", - "@actions/exec": "^1.1.1", - "@actions/github": "^6.0.0", - "@actions/glob": "^0.4.0", - "@actions/io": "^1.1.3", - "@octokit/core": "^5.0.1", - "@octokit/plugin-request-log": "^4.0.0", - "@octokit/plugin-retry": "^6.0.1", - "@types/node": "^20.9.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { - "node": ">=20.0.0 <21.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@types/node": { - "version": "20.17.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz", - "integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==", + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.19.2" + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "license": "Apache-2.0" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/bottleneck": { - "version": "2.19.5", - "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", - "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, - "license": "ISC" + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": "*" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.26.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", + "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.3", + "@babel/parser": "^7.26.3", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.3", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz", + "integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.3.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.5.tgz", + "integrity": "sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.0.tgz", + "integrity": "sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^8.3.0", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz", + "integrity": "sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^12.6.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^20.0.0" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", + "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz", + "integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^12.6.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^20.0.0" + } + }, + "node_modules/@octokit/plugin-retry": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-6.1.0.tgz", + "integrity": "sha512-WrO3bvq4E1Xh1r2mT9w6SDFg01gFmP81nIG77+p/MqW1JeXXgL++6umim3t6x0Zj5pZm3rXAN+0HEjmmdhIRig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^13.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/request": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.0.tgz", + "integrity": "sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^9.0.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.0.tgz", + "integrity": "sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/types": { + "version": "13.6.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.2.tgz", + "integrity": "sha512-WpbZfZUcZU77DrSW4wbsSgTPfKcp286q3ItaIgvSbBpZJlu6mnYXAkjZz6LVZPXkEvLIM8McanyZejKTYUHipA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/github-script": { + "name": "github-script", + "version": "7.0.1", + "resolved": "git+ssh://git@github.com/actions/github-script.git#4020e461acd7a80762cdfff123a1fde368246fa4", + "dev": true, + "license": "MIT", + "dependencies": { + "@actions/core": "^1.10.1", + "@actions/exec": "^1.1.1", + "@actions/github": "^6.0.0", + "@actions/glob": "^0.4.0", + "@actions/io": "^1.1.3", + "@octokit/core": "^5.0.1", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-retry": "^6.0.1", + "@types/node": "^20.9.0" + }, + "engines": { + "node": ">=20.0.0 <21.0.0" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/node": { + "version": "20.17.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz", + "integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz", + "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001690", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", + "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", + "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.76", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.76.tgz", + "integrity": "sha512-CjVQyG7n7Sr+eBXE86HIulnL5N8xZY1sgmOPGuq/F0Rr0FJq63lg0kEtOIDfZBk44FnDLf6FUJ+dsJcuiUDdDQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/once": { @@ -381,7 +3229,541 @@ "dev": true, "license": "ISC", "dependencies": { - "wrappy": "1" + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" } }, "node_modules/tunnel": { @@ -394,6 +3776,29 @@ "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/undici": { "version": "5.28.4", "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", @@ -421,12 +3826,175 @@ "dev": true, "license": "ISC" }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true, "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index e658149..1f9f051 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,10 @@ { "type": "module", + "scripts": { + "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js" + }, "devDependencies": { - "@types/github-script": "github:actions/github-script" + "@types/github-script": "github:actions/github-script", + "jest": "^29.7.0" } } From 149c3fbf7c643f778f632e908685ae8f4b925f65 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Sat, 28 Dec 2024 13:20:17 +0100 Subject: [PATCH 34/93] ci: changed the name of the job of the action scripts tests --- .github/workflows/actions-scripts-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/actions-scripts-tests.yml b/.github/workflows/actions-scripts-tests.yml index a2bb31e..46af99e 100644 --- a/.github/workflows/actions-scripts-tests.yml +++ b/.github/workflows/actions-scripts-tests.yml @@ -9,7 +9,7 @@ on: - 'actions_scripts/**' # Run on PRs affecting the actions_scripts folder jobs: - test-and-coverage: + test-and-coverage-action-scripts: runs-on: ubuntu-latest steps: From c288c8458c1f41cd738c972cf1e9838d46aec969 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Sat, 28 Dec 2024 18:58:00 +0100 Subject: [PATCH 35/93] ci: including the jest tests report on a comment on the active PR --- .github/workflows/actions-scripts-tests.yml | 36 +++++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/.github/workflows/actions-scripts-tests.yml b/.github/workflows/actions-scripts-tests.yml index 46af99e..3634e3a 100644 --- a/.github/workflows/actions-scripts-tests.yml +++ b/.github/workflows/actions-scripts-tests.yml @@ -27,6 +27,36 @@ jobs: - name: Install dependencies run: npm ci - # Run tests and collect coverage - - name: Run tests and generate coverage - run: npm test \ No newline at end of file + # Run tests and capture output + - name: Run tests + id: run_tests + run: | + { + echo 'tests_report<&1 + echo EOF + } >> "$GITHUB_OUTPUT" + + # Post comment on PR + - name: Add JEST results as a PR comment + uses: actions/github-script@v7 + with: + script: | + const steps = ${{ toJSON(steps) }}; + const marker = 'to show where the warning was created)'; + const output = steps.run_tests.outputs.tests_report; + const sanitized = output.split(marker); + const msg = (sanitized.length > 1) ? sanitized[1] : sanitized[0]; + + const prNumber = context.payload.issue.number; + + if (sanitized.length >= 1) { + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: msg, + }); + } else { + core.setFailed('No tests report data available.') + } \ No newline at end of file From 0b23e826bf245bdd11928b1e9e7ae166f9ea3f88 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Sat, 28 Dec 2024 19:10:16 +0100 Subject: [PATCH 36/93] ci: refactoring the tests-report step into their own ECMAscript module --- .github/workflows/actions-scripts-tests.yml | 22 ++++---------- actions_scripts/helpers.js | 20 +++++++++++-- actions_scripts/notify_user.js | 20 +------------ actions_scripts/tests_report_on_pr_comment.js | 30 +++++++++++++++++++ 4 files changed, 53 insertions(+), 39 deletions(-) create mode 100644 actions_scripts/tests_report_on_pr_comment.js diff --git a/.github/workflows/actions-scripts-tests.yml b/.github/workflows/actions-scripts-tests.yml index 3634e3a..32e1e90 100644 --- a/.github/workflows/actions-scripts-tests.yml +++ b/.github/workflows/actions-scripts-tests.yml @@ -43,20 +43,8 @@ jobs: with: script: | const steps = ${{ toJSON(steps) }}; - const marker = 'to show where the warning was created)'; - const output = steps.run_tests.outputs.tests_report; - const sanitized = output.split(marker); - const msg = (sanitized.length > 1) ? sanitized[1] : sanitized[0]; - - const prNumber = context.payload.issue.number; - - if (sanitized.length >= 1) { - github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - body: msg, - }); - } else { - core.setFailed('No tests report data available.') - } \ No newline at end of file + + const { default: testReportOnPrComment } = + await import('${{ github.workspace }}/actions_scripts/tests_report_on_pr_comment.js'); + + await testReportOnPrComment(github, context, steps); \ No newline at end of file diff --git a/actions_scripts/helpers.js b/actions_scripts/helpers.js index a2d155d..ae7c85b 100644 --- a/actions_scripts/helpers.js +++ b/actions_scripts/helpers.js @@ -1,7 +1,6 @@ // Contains helper functions made to be reusable across the JS scripts // of the notifications -// Helper function to determine if the workflow is running locally. /** * Check if the current run is a local run (e.g., with ACT). * @param {Object} context - GitHub Actions context object. @@ -12,7 +11,23 @@ export function ciLocalRun(context) { return (localRun !== undefined) ? localRun : false; } -// Helper function to retrieve the username of the actor triggering the workflow. +/** + * Post a comment on the PR to notify the user. + * @param {Object} github - GitHub API client. + * @param {Object} context - GitHub Actions context object. + * @param {number} prNumber - Pull request number. + * @param {string} message - Message content to be posted. + * @returns {Object} - The response object from the GitHub API. + */ +export async function createPrComment(github, context, prNumber, message) { + return await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: message, + }); +} + /** * Get the username of the actor from the context. * @param {Object} context - GitHub Actions context object. @@ -27,7 +42,6 @@ export function extractUsername(context) { throw new Error("Unable to determine the actor (user) that triggered this deploy. Leaving..."); } -// Helper function to retrieve the owner of the repository in which the action has been triggered. /** * Get the username of the actor from the context. * @param {Object} context - GitHub Actions context object. diff --git a/actions_scripts/notify_user.js b/actions_scripts/notify_user.js index 3d4c3b9..b67e560 100644 --- a/actions_scripts/notify_user.js +++ b/actions_scripts/notify_user.js @@ -1,4 +1,4 @@ -import { ciLocalRun, extractUsername } from "./helpers.js"; +import { ciLocalRun, extractUsername, createPrComment } from "./helpers.js"; /** * Notify the user about the deployment action. @@ -56,24 +56,6 @@ function generatePrCommentMsg(username, environment, project, infra) { return message; } -// Helper function to create a PR comment via the GitHub API. -/** - * Post a comment on the PR to notify the user. - * @param {Object} github - GitHub API client. - * @param {Object} context - GitHub Actions context object. - * @param {number} prNumber - Pull request number. - * @param {string} message - Message content to be posted. - * @returns {Object} - The response object from the GitHub API. - */ -async function createPrComment(github, context, prNumber, message) { - return await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - body: message, - }); -} - // Helper function to log the PR comment message in a local environment. /** * Log the message locally for debugging when running with ACT. diff --git a/actions_scripts/tests_report_on_pr_comment.js b/actions_scripts/tests_report_on_pr_comment.js new file mode 100644 index 0000000..d2080d0 --- /dev/null +++ b/actions_scripts/tests_report_on_pr_comment.js @@ -0,0 +1,30 @@ +import { ciLocalRun, getRepoOwner } from "./helpers.js"; + +/** + * Generates a new comment on the PR that triggered the workflow with the + * report of the tests runned by 'JEST' over the actions scripts + */ +export default async (github, context, steps) => { + const isLocalRun = ciLocalRun(context); + + const marker = 'to show where the warning was created)'; + const output = steps.run_tests.outputs.tests_report; + const sanitized = output.split(marker); + const msg = (sanitized.length > 1) ? sanitized[1] : sanitized[0]; + + const prNumber = context.payload.issue.number; + + if (!isLocalRun && sanitized.length >= 1) { + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: msg, + }); + } else { + if (!isLocalRun) + core.setFailed('No tests report data available.'); + else + console.log(`PR message: ${msg}`); + } +}; \ No newline at end of file From e46ff3b13be41c5186bdf652b8a090aae08bc718 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Sat, 28 Dec 2024 19:16:28 +0100 Subject: [PATCH 37/93] ci(debug): logging the context --- .github/workflows/actions-scripts-tests.yml | 3 --- actions_scripts/tests_report_on_pr_comment.js | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/actions-scripts-tests.yml b/.github/workflows/actions-scripts-tests.yml index 32e1e90..755dd2a 100644 --- a/.github/workflows/actions-scripts-tests.yml +++ b/.github/workflows/actions-scripts-tests.yml @@ -1,9 +1,6 @@ name: Test Action Scripts on: - push: - paths: - - 'actions_scripts/**' # Trigger only when files in this folder are modified pull_request: paths: - 'actions_scripts/**' # Run on PRs affecting the actions_scripts folder diff --git a/actions_scripts/tests_report_on_pr_comment.js b/actions_scripts/tests_report_on_pr_comment.js index d2080d0..0f2b69a 100644 --- a/actions_scripts/tests_report_on_pr_comment.js +++ b/actions_scripts/tests_report_on_pr_comment.js @@ -6,7 +6,7 @@ import { ciLocalRun, getRepoOwner } from "./helpers.js"; */ export default async (github, context, steps) => { const isLocalRun = ciLocalRun(context); - + console.log('CTX: ${JSON.stringify(context, null, 2)}'); const marker = 'to show where the warning was created)'; const output = steps.run_tests.outputs.tests_report; const sanitized = output.split(marker); From 899f6cf7798c6c69e95cb5cfcf99848faa4737f6 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Sat, 28 Dec 2024 19:18:10 +0100 Subject: [PATCH 38/93] fix: missing interpolation quotes --- actions_scripts/tests_report_on_pr_comment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions_scripts/tests_report_on_pr_comment.js b/actions_scripts/tests_report_on_pr_comment.js index 0f2b69a..fd0d519 100644 --- a/actions_scripts/tests_report_on_pr_comment.js +++ b/actions_scripts/tests_report_on_pr_comment.js @@ -6,7 +6,7 @@ import { ciLocalRun, getRepoOwner } from "./helpers.js"; */ export default async (github, context, steps) => { const isLocalRun = ciLocalRun(context); - console.log('CTX: ${JSON.stringify(context, null, 2)}'); + console.log(`CTX: ${JSON.stringify(context, null, 2)}`); const marker = 'to show where the warning was created)'; const output = steps.run_tests.outputs.tests_report; const sanitized = output.split(marker); From 398aa51fdc3b9233239ac39bdf2f9dba01eec8e9 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Sat, 28 Dec 2024 19:21:43 +0100 Subject: [PATCH 39/93] ci(fix): resolving the number of the pr on a different prop of the 'context' object --- .github/workflows/mock_payloads/deploy_act.json | 1 + actions_scripts/tests_report_on_pr_comment.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/mock_payloads/deploy_act.json b/.github/workflows/mock_payloads/deploy_act.json index 6aa8a20..badd7a4 100644 --- a/.github/workflows/mock_payloads/deploy_act.json +++ b/.github/workflows/mock_payloads/deploy_act.json @@ -1,5 +1,6 @@ { "act": true, + "number": 10, "action": "created", "comment": { "author_association": "MEMBER", diff --git a/actions_scripts/tests_report_on_pr_comment.js b/actions_scripts/tests_report_on_pr_comment.js index fd0d519..c6e725a 100644 --- a/actions_scripts/tests_report_on_pr_comment.js +++ b/actions_scripts/tests_report_on_pr_comment.js @@ -12,7 +12,7 @@ export default async (github, context, steps) => { const sanitized = output.split(marker); const msg = (sanitized.length > 1) ? sanitized[1] : sanitized[0]; - const prNumber = context.payload.issue.number; + const prNumber = context.payload.number; if (!isLocalRun && sanitized.length >= 1) { github.rest.issues.createComment({ From 2473421e020f617ea45ee9dba05688946cd16cfd Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Sat, 28 Dec 2024 19:41:49 +0100 Subject: [PATCH 40/93] ci: stylizing the tests report --- actions_scripts/tests_report_on_pr_comment.js | 58 +++++++++++++++---- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/actions_scripts/tests_report_on_pr_comment.js b/actions_scripts/tests_report_on_pr_comment.js index c6e725a..2ddb720 100644 --- a/actions_scripts/tests_report_on_pr_comment.js +++ b/actions_scripts/tests_report_on_pr_comment.js @@ -1,4 +1,4 @@ -import { ciLocalRun, getRepoOwner } from "./helpers.js"; +import { ciLocalRun, createPrComment } from "./helpers.js"; /** * Generates a new comment on the PR that triggered the workflow with the @@ -6,25 +6,61 @@ import { ciLocalRun, getRepoOwner } from "./helpers.js"; */ export default async (github, context, steps) => { const isLocalRun = ciLocalRun(context); - console.log(`CTX: ${JSON.stringify(context, null, 2)}`); + const prNumber = context.payload.number; + const marker = 'to show where the warning was created)'; const output = steps.run_tests.outputs.tests_report; const sanitized = output.split(marker); - const msg = (sanitized.length > 1) ? sanitized[1] : sanitized[0]; + + let msg = getTitleMsg(); + msg += (sanitized.length > 1) ? sanitized[1] : sanitized[0]; - const prNumber = context.payload.number; + const stylizedMsg = formatTestOutput(msg); if (!isLocalRun && sanitized.length >= 1) { - github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - body: msg, - }); + createPrComment(github, context, prNumber, stylizedMsg); } else { if (!isLocalRun) core.setFailed('No tests report data available.'); else console.log(`PR message: ${msg}`); } -}; \ No newline at end of file +}; + +/** + * @return {string} a title message for the automated comment on the target PR + * that decorates such comment with a nice title + */ +function getTitleMsg() { + return "This message is autogenerated, because there's changes in the " + + "'actions-scripts' folder, which contains JS code that is used for by some " + + "automations in our workflows.\n" +} + +/** + * Gives formats and stylizes the generated tests reports of 'JEST' to be shown + * on the PR comment to notify the user about the test results. + * @param {string} textMsg the input data with the tests results as a report + * @returns {string} the tests report formatted and stylized + */ +export function formatTestOutput(textMsg) { + return textMsg + .split('\n') + .map(line => { + if (line.includes('✓')) { + return `\t- ✅ ${line.trim()}`; + } + if (line.includes('✗')) { + return `\t- ❌ ${line.trim()}`; + } + if (line.startsWith('PASS')) { + return `🎉 ${line}`; + } + if (line.startsWith('FAIL')) { + return `💥 ${line}`; + } + return `\t ${line.trim()}`; + }) + .join('\n'); + } + From 3165e21978e0485c94abeccd20384bca32ebbf63 Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Sat, 28 Dec 2024 19:44:15 +0100 Subject: [PATCH 41/93] ci: better style on the tests report --- actions_scripts/tests_report_on_pr_comment.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/actions_scripts/tests_report_on_pr_comment.js b/actions_scripts/tests_report_on_pr_comment.js index 2ddb720..5bec641 100644 --- a/actions_scripts/tests_report_on_pr_comment.js +++ b/actions_scripts/tests_report_on_pr_comment.js @@ -12,10 +12,9 @@ export default async (github, context, steps) => { const output = steps.run_tests.outputs.tests_report; const sanitized = output.split(marker); - let msg = getTitleMsg(); - msg += (sanitized.length > 1) ? sanitized[1] : sanitized[0]; + let msg = (sanitized.length > 1) ? sanitized[1] : sanitized[0]; - const stylizedMsg = formatTestOutput(msg); + const stylizedMsg = getTitleMsg() + formatTestOutput(msg); if (!isLocalRun && sanitized.length >= 1) { createPrComment(github, context, prNumber, stylizedMsg); @@ -59,7 +58,7 @@ export function formatTestOutput(textMsg) { if (line.startsWith('FAIL')) { return `💥 ${line}`; } - return `\t ${line.trim()}`; + return `\t${line.trim()}`; }) .join('\n'); } From 46b7853321a87911951eacea17bd93fe91f64ff8 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 5 Jan 2025 19:17:33 +0100 Subject: [PATCH 42/93] ci: :sparkles: Basic infrastructure deployment workflow added. --- .github/workflows/deploy-chatbot.yml | 17 +++++++++-------- .github/workflows/deploy-infra.yml | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/deploy-infra.yml diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 61d75f7..58dcc6f 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -80,6 +80,7 @@ jobs: details: details, }; + - name: Deploy Infra if: steps.parse_command.outputs.infra != '' uses: appleboy/ssh-action@v1.2.0 @@ -91,22 +92,19 @@ jobs: case "${{ steps.parse_command.outputs.infra }}" in postgres) echo "Deploying Postgres..." - docker run -d --name postgres --restart always -e POSTGRES_PASSWORD=mysecretpassword postgres ;; redis) echo "Deploying Redis..." - docker run -d --name redis --restart always redis - ;; - all) - echo "Deploying Postgres and Redis..." - docker run -d --name postgres --restart always -e POSTGRES_PASSWORD=mysecretpassword postgres - docker run -d --name redis --restart always redis ;; *) echo "Unknown infra: ${{ steps.parse_command.outputs.infra }}" + exit 1 ;; esac + echo 'artifact="${{ steps.parse_command.outputs.infra }}"' >> $GITHUB_ENV + echo 'environment="${{ steps.parse_command.outputs.environment }}"' >> $GITHUB_ENV + - name: Update Deployment Status uses: actions/github-script@v7 id: update-comment-with-deployment-status @@ -117,4 +115,7 @@ jobs: const { default: updatePrComment } = await import('${{ github.workspace }}/actions_scripts/update_pr_comment.js'); - await updatePrComment(github, context, steps); \ No newline at end of file + await updatePrComment(github, context, steps); + + call-deploy-infra-artifact: + uses: zerodaycode/app-summoners-sync/.github/workflows/deploy-infra.yml@develop \ No newline at end of file diff --git a/.github/workflows/deploy-infra.yml b/.github/workflows/deploy-infra.yml new file mode 100644 index 0000000..b6975a7 --- /dev/null +++ b/.github/workflows/deploy-infra.yml @@ -0,0 +1,18 @@ +on: + workflow_call: + inputs: + artifact: + required: true + type: string + environment: + required: true + type: string +jobs: + deploy_infra_artifact: + runs-on: ubuntu-latest + steps: + - name: Build compose filename + id: build-compose-filename + run: | + echo "Artifact: ${{ inputs.artifact }}" + echo "Environment: ${{ inputs.environment }}" \ No newline at end of file From 4ce4a5a75ef480165d5b3c67c0220da66f400a5b Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 5 Jan 2025 19:28:29 +0100 Subject: [PATCH 43/93] chore: :art: getting the output of the first job as an input of the second one (deploy) --- .github/workflows/deploy-chatbot.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 58dcc6f..0f70d2e 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -118,4 +118,8 @@ jobs: await updatePrComment(github, context, steps); call-deploy-infra-artifact: - uses: zerodaycode/app-summoners-sync/.github/workflows/deploy-infra.yml@develop \ No newline at end of file + needs: handle-deployment-on-pr-comment + uses: zerodaycode/app-summoners-sync/.github/workflows/deploy-infra.yml@develop + with: + artifact: ${{ needs.handle-deployment-on-pr-comment.outputs.artifact }} + environment: ${{ needs.handle-deployment-on-pr-comment.outputs.environment }} \ No newline at end of file From 6a9999c50fe2b05ef95371ce61c47e69ebcb5418 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 5 Jan 2025 19:31:47 +0100 Subject: [PATCH 44/93] fix: wrong workflow abort logic --- .../infra/docker/postgres-compose-pre.yml | 19 +++++++++++++++++++ actions_scripts/parse_deployment_command.js | 8 ++++---- 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/infra/docker/postgres-compose-pre.yml diff --git a/.github/workflows/infra/docker/postgres-compose-pre.yml b/.github/workflows/infra/docker/postgres-compose-pre.yml new file mode 100644 index 0000000..f9ddc47 --- /dev/null +++ b/.github/workflows/infra/docker/postgres-compose-pre.yml @@ -0,0 +1,19 @@ +version: '3.8' + +services: + postgres: + image: postgres:17 + container_name: postgres + restart: always + environment: + POSTGRES_USER: yourusername # Replace with your desired username + POSTGRES_PASSWORD: yourpassword # Replace with your desired password + POSTGRES_DB: yourdatabase # Replace with your desired database name + ports: + - "5432:5432" # Maps port 5432 on the host to port 5432 in the container + volumes: + - postgres_data:/var/lib/postgresql/data # Persistent data storage + +volumes: + postgres_data: + driver: local diff --git a/actions_scripts/parse_deployment_command.js b/actions_scripts/parse_deployment_command.js index 5cb396f..ca8aa4c 100644 --- a/actions_scripts/parse_deployment_command.js +++ b/actions_scripts/parse_deployment_command.js @@ -5,7 +5,7 @@ * @param {Object} options.core module for interacting with GitHub Actions workflow commands and outputs. */ export default ({context, core}) => { - const localRun = !context.payload.act; + const localRun = context.payload.act; let commentBody = context.payload.comment?.body || ''; if (localRun) @@ -22,6 +22,9 @@ export default ({context, core}) => { if (environmentMatch) { environment = environmentMatch[1]; console.log(`Environment: ${environment}`); + } else { + core.setFailed("No environment specified. Aborting workflow."); + return; } // Parse project @@ -29,9 +32,6 @@ export default ({context, core}) => { if (projectMatch) { project = projectMatch[1]; console.log(`Project: ${project}`); - } else { - core.setFailed("No project specified. Aborting workflow."); - return; } // Parse infra From 153445129015572f56bc63876a09658e1a94c3f9 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 5 Jan 2025 19:33:54 +0100 Subject: [PATCH 45/93] fix: wrong uses case with ssh over the deploy action --- .github/workflows/deploy-chatbot.yml | 35 ++++++++++++---------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 0f70d2e..95bab8d 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -83,26 +83,21 @@ jobs: - name: Deploy Infra if: steps.parse_command.outputs.infra != '' - uses: appleboy/ssh-action@v1.2.0 - with: - host: ${{ secrets.SSH_HOST }} - username: ${{ secrets.SSH_USERNAME }} - key: ${{ secrets.SSH_KEY }} - script: | - case "${{ steps.parse_command.outputs.infra }}" in - postgres) - echo "Deploying Postgres..." - ;; - redis) - echo "Deploying Redis..." - ;; - *) - echo "Unknown infra: ${{ steps.parse_command.outputs.infra }}" - exit 1 - ;; - esac - echo 'artifact="${{ steps.parse_command.outputs.infra }}"' >> $GITHUB_ENV - echo 'environment="${{ steps.parse_command.outputs.environment }}"' >> $GITHUB_ENV + run: | + case "${{ steps.parse_command.outputs.infra }}" in + postgres) + echo "Deploying Postgres..." + ;; + redis) + echo "Deploying Redis..." + ;; + *) + echo "Unknown infra: ${{ steps.parse_command.outputs.infra }}" + exit 1 + ;; + esac + echo 'artifact="${{ steps.parse_command.outputs.infra }}"' >> $GITHUB_ENV + echo 'environment="${{ steps.parse_command.outputs.environment }}"' >> $GITHUB_ENV - name: Update Deployment Status From f4891d4c3d00005aebc8da81a1b85f377500e133 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 5 Jan 2025 19:36:39 +0100 Subject: [PATCH 46/93] chore: avoiding the update pr on comment while developing the infra action --- .github/workflows/deploy-chatbot.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 95bab8d..c3cedf5 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -101,6 +101,7 @@ jobs: - name: Update Deployment Status + if: steps.parse_command.outputs.project != '' # TODO provisional ñapa while we don't add the remaining outputs uses: actions/github-script@v7 id: update-comment-with-deployment-status with: From 33b21c36094c87349b1081e3f770c60b23e79daa Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 5 Jan 2025 19:42:38 +0100 Subject: [PATCH 47/93] chore(gh-actions): :bug: Tentative fix for workflow outputs --- .github/workflows/deploy-chatbot.yml | 3 +++ .vscode/settings.json | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index c3cedf5..1268087 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -8,6 +8,9 @@ on: jobs: handle-deployment-on-pr-comment: runs-on: ubuntu-latest + outputs: + artifact: ${{ steps.parse_command.outputs.infra }} + environment: ${{ steps.parse_command.outputs.environment }} steps: - uses: actions/checkout@v4 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..11265dc --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "conventionalCommits.scopes": [ + "gh-actions" + ] +} \ No newline at end of file From be1e36aa699a8eb12943db566c8b32b3ab6d47b0 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 5 Jan 2025 20:01:18 +0100 Subject: [PATCH 48/93] chore: :lock: Update .gitignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 723ef1d..37ccd87 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ .nvim/ .idea/ -node_modules/ \ No newline at end of file +node_modules/ + +.env \ No newline at end of file From 1a5100c192afd366ca56e9d0a0273cce4327046e Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 5 Jan 2025 20:02:08 +0100 Subject: [PATCH 49/93] chore: :art: Improve postgres compose. --- .../workflows/infra/docker/postgres-compose-pre.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/infra/docker/postgres-compose-pre.yml b/.github/workflows/infra/docker/postgres-compose-pre.yml index f9ddc47..64a8071 100644 --- a/.github/workflows/infra/docker/postgres-compose-pre.yml +++ b/.github/workflows/infra/docker/postgres-compose-pre.yml @@ -6,13 +6,13 @@ services: container_name: postgres restart: always environment: - POSTGRES_USER: yourusername # Replace with your desired username - POSTGRES_PASSWORD: yourpassword # Replace with your desired password - POSTGRES_DB: yourdatabase # Replace with your desired database name + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: ${POSTGRES_DB} ports: - - "5432:5432" # Maps port 5432 on the host to port 5432 in the container + - "5432:5432" volumes: - - postgres_data:/var/lib/postgresql/data # Persistent data storage + - postgres_data:/var/lib/postgresql/data volumes: postgres_data: From 2844086e06db175fd718e7887389d80ca627784f Mon Sep 17 00:00:00 2001 From: Alex Vergara Date: Mon, 6 Jan 2025 13:11:02 +0100 Subject: [PATCH 50/93] feat: Initial SQL data schema and tables creation for testing on our PRE env --- .../infra/docker/Summoners Sync Tables.sql | 35 +++++++++++++++++++ .../infra/docker/postgres-compose-pre.yml | 13 +++++-- 2 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/infra/docker/Summoners Sync Tables.sql diff --git a/.github/workflows/infra/docker/Summoners Sync Tables.sql b/.github/workflows/infra/docker/Summoners Sync Tables.sql new file mode 100644 index 0000000..38eaf01 --- /dev/null +++ b/.github/workflows/infra/docker/Summoners Sync Tables.sql @@ -0,0 +1,35 @@ +-- Summoners Sync schema and tables creation and roles initial data + +-- Create the SS schema +CREATE schema summonerssync; + +-- Create the users table +CREATE TABLE summonerssync.users ( + id SERIAL PRIMARY KEY, + username VARCHAR(50) UNIQUE NOT NULL, + email VARCHAR(100) UNIQUE NOT NULL, + password_hash TEXT NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- Create the roles table +CREATE TABLE summonerssync.roles ( + id SERIAL PRIMARY KEY, + name VARCHAR(50) UNIQUE NOT NULL, + description TEXT +); + +-- Create the user_roles table to associate users with roles (many-to-many) +CREATE TABLE summonerssync.user_roles ( + user_id INT NOT NULL, + role_id INT NOT NULL, + PRIMARY KEY (user_id, role_id), + FOREIGN KEY (user_id) REFERENCES summonerssync.users(id) ON DELETE CASCADE, + FOREIGN KEY (role_id) REFERENCES summonerssync.roles(id) ON DELETE CASCADE +); + +-- Add default roles +INSERT INTO summonerssync.roles (name, description) VALUES +('ADMIN', 'Full access to the system'), +('USER', 'Limited access to the system'), +('DEVELOPER', 'External contributor with restricted access'); diff --git a/.github/workflows/infra/docker/postgres-compose-pre.yml b/.github/workflows/infra/docker/postgres-compose-pre.yml index 64a8071..c34ac24 100644 --- a/.github/workflows/infra/docker/postgres-compose-pre.yml +++ b/.github/workflows/infra/docker/postgres-compose-pre.yml @@ -1,9 +1,7 @@ -version: '3.8' - services: postgres: image: postgres:17 - container_name: postgres + container_name: postgres-summoners-sync restart: always environment: POSTGRES_USER: ${POSTGRES_USER} @@ -13,6 +11,15 @@ services: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data + networks: + postgres_network: + ipv4_address: 172.20.0.10 +networks: + postgres_network: + driver: bridge + ipam: + config: + - subnet: 172.20.0.0/16 volumes: postgres_data: From 40936273d8145c98a637a754c20ae19577f56076 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Tue, 7 Jan 2025 15:27:29 +0100 Subject: [PATCH 51/93] feat(gh-actions): :sparkles: Added steps to upload infra to DO --- .github/workflows/deploy-infra.yml | 62 ++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/.github/workflows/deploy-infra.yml b/.github/workflows/deploy-infra.yml index b6975a7..2df4523 100644 --- a/.github/workflows/deploy-infra.yml +++ b/.github/workflows/deploy-infra.yml @@ -1,18 +1,48 @@ on: - workflow_call: - inputs: - artifact: - required: true - type: string - environment: - required: true - type: string + workflow_call: + inputs: + artifact: + required: true + type: string + environment: + required: true + type: string + secret_name: + required: true + type: string jobs: - deploy_infra_artifact: - runs-on: ubuntu-latest - steps: - - name: Build compose filename - id: build-compose-filename - run: | - echo "Artifact: ${{ inputs.artifact }}" - echo "Environment: ${{ inputs.environment }}" \ No newline at end of file + deploy_infra_artifact: + runs-on: ubuntu-latest + steps: + - name: Build compose filename + id: build-compose-filename + run: | + echo "Artifact: ${{ inputs.artifact }}" + echo "Environment: ${{ inputs.environment }}" + filename="${{ inputs.artifact }}-compose-${{ inputs.environment }}.yml" + echo "Generated filename: $filename" + echo "COMPOSE_FILENAME=$filename" >> $GITHUB_ENV + + - name: Transfer Compose File to Server + uses: appleboy/scp-action@v0.1.7 + with: + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USERNAME }} + key: ${{ secrets.SSH_KEY }} + source: .github/workflows/infra/docker/postgres-compose-pre.yml + target: /opt/summoners-sync/infra/docker/${{ env.COMPOSE_FILENAME }} + rm: true + + # Deploy Infra + - name: Deploy Infra + uses: appleboy/ssh-action@v1.2.0 + with: + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USERNAME }} + key: ${{ secrets.SSH_KEY }} + script: | + cd /opt/summoners-sync/infra/docker + + echo "${{ secrets[inputs.secret_name] }}" > .env + + docker-compose --env-file .env -f ${{ env.COMPOSE_FILENAME }} up -d \ No newline at end of file From 545b4599c7ef8c5996d00ff80546e2df68a1c2cd Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Tue, 7 Jan 2025 15:30:06 +0100 Subject: [PATCH 52/93] chore(gh-actions): Added debug step --- .github/workflows/deploy-infra.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/deploy-infra.yml b/.github/workflows/deploy-infra.yml index 2df4523..22701d2 100644 --- a/.github/workflows/deploy-infra.yml +++ b/.github/workflows/deploy-infra.yml @@ -23,6 +23,10 @@ jobs: echo "Generated filename: $filename" echo "COMPOSE_FILENAME=$filename" >> $GITHUB_ENV + - name: Debug secret name + run: | + echo "secret name : ${{ inputs.secret_name }}" + - name: Transfer Compose File to Server uses: appleboy/scp-action@v0.1.7 with: From 5ef0df10631dc5bbb6e9e37a887a6c54af440ff2 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Tue, 7 Jan 2025 15:32:33 +0100 Subject: [PATCH 53/93] feat(gh-actions): :sparkles: Added new output to pass to reusable workflow --- .github/workflows/deploy-chatbot.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 1268087..6d8cde3 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -11,6 +11,7 @@ jobs: outputs: artifact: ${{ steps.parse_command.outputs.infra }} environment: ${{ steps.parse_command.outputs.environment }} + secret_name: ${{ steps.deploy-infra.outputs.secret_name}} steps: - uses: actions/checkout@v4 @@ -85,6 +86,7 @@ jobs: - name: Deploy Infra + id: deploy-infra if: steps.parse_command.outputs.infra != '' run: | case "${{ steps.parse_command.outputs.infra }}" in @@ -99,8 +101,13 @@ jobs: exit 1 ;; esac - echo 'artifact="${{ steps.parse_command.outputs.infra }}"' >> $GITHUB_ENV - echo 'environment="${{ steps.parse_command.outputs.environment }}"' >> $GITHUB_ENV + INFRA_UPPER=$(echo "${{ inputs.artifact }}" | tr 'a-z' 'A-Z') + ENV_UPPER=$(echo "${{ inputs.environment }}" | tr 'a-z' 'A-Z') + + SECRET_NAME="SS_${INFRA_UPPER}_${ENV_UPPER}" + + echo "Generated secret_name: $secret_name" + echo "SECRET_NAME=$secret_name" >> $GITHUB_OUTPUT - name: Update Deployment Status @@ -121,4 +128,7 @@ jobs: uses: zerodaycode/app-summoners-sync/.github/workflows/deploy-infra.yml@develop with: artifact: ${{ needs.handle-deployment-on-pr-comment.outputs.artifact }} - environment: ${{ needs.handle-deployment-on-pr-comment.outputs.environment }} \ No newline at end of file + environment: ${{ needs.handle-deployment-on-pr-comment.outputs.environment }} + secret_name: ${{ needs.handle-deployment-on-pr-comment.outputs.secret_name }} + secrets: inherit + From 3e7ab46ac5e21471bf2a8381be76f7e6d2f706a4 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Tue, 7 Jan 2025 15:39:05 +0100 Subject: [PATCH 54/93] fix(gh-actions): :bug: Fix secret variable name and Uppercase access --- .github/workflows/deploy-chatbot.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 6d8cde3..6f2f060 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -101,10 +101,10 @@ jobs: exit 1 ;; esac - INFRA_UPPER=$(echo "${{ inputs.artifact }}" | tr 'a-z' 'A-Z') - ENV_UPPER=$(echo "${{ inputs.environment }}" | tr 'a-z' 'A-Z') + INFRA_UPPER=$(echo "${{steps.parse_command.outputs.environment }}" | tr 'a-z' 'A-Z') + ENV_UPPER=$(echo "${{ steps.parse_command.outputs.environment }}" | tr 'a-z' 'A-Z') - SECRET_NAME="SS_${INFRA_UPPER}_${ENV_UPPER}" + secret_name="SS_${INFRA_UPPER}_${ENV_UPPER}" echo "Generated secret_name: $secret_name" echo "SECRET_NAME=$secret_name" >> $GITHUB_OUTPUT From 09000fcd44d7d0a3d516cf687801d3107304221c Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Tue, 7 Jan 2025 15:41:14 +0100 Subject: [PATCH 55/93] fix(gh-actions): :bug: Fix infra uppercase variable --- .github/workflows/deploy-chatbot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 6f2f060..0585bb4 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -101,7 +101,7 @@ jobs: exit 1 ;; esac - INFRA_UPPER=$(echo "${{steps.parse_command.outputs.environment }}" | tr 'a-z' 'A-Z') + INFRA_UPPER=$(echo "${{steps.parse_command.outputs.infra }}" | tr 'a-z' 'A-Z') ENV_UPPER=$(echo "${{ steps.parse_command.outputs.environment }}" | tr 'a-z' 'A-Z') secret_name="SS_${INFRA_UPPER}_${ENV_UPPER}" From b8f412ab09026771c6ac28351162c013c6ba8344 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Tue, 7 Jan 2025 15:44:21 +0100 Subject: [PATCH 56/93] chore(gh-actions): :rocket: Update SSH secrets to use organization ones. --- .github/workflows/deploy-infra.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy-infra.yml b/.github/workflows/deploy-infra.yml index 22701d2..4836697 100644 --- a/.github/workflows/deploy-infra.yml +++ b/.github/workflows/deploy-infra.yml @@ -30,9 +30,9 @@ jobs: - name: Transfer Compose File to Server uses: appleboy/scp-action@v0.1.7 with: - host: ${{ secrets.SSH_HOST }} - username: ${{ secrets.SSH_USERNAME }} - key: ${{ secrets.SSH_KEY }} + host: ${{ secrets.DO_SSH_HOST_PRE }} + username: ${{ secrets.DO_SSH_USER_PRE }} + key: ${{ secrets.DO_SSH_KEY_PRE }} source: .github/workflows/infra/docker/postgres-compose-pre.yml target: /opt/summoners-sync/infra/docker/${{ env.COMPOSE_FILENAME }} rm: true @@ -41,9 +41,9 @@ jobs: - name: Deploy Infra uses: appleboy/ssh-action@v1.2.0 with: - host: ${{ secrets.SSH_HOST }} - username: ${{ secrets.SSH_USERNAME }} - key: ${{ secrets.SSH_KEY }} + host: ${{ secrets.DO_SSH_HOST_PRE }} + username: ${{ secrets.DO_SSH_USER_PRE }} + key: ${{ secrets.DO_SSH_KEY_PRE }} script: | cd /opt/summoners-sync/infra/docker From 51402347246bb8b94bf7c15594bbc851fa0d30c7 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Tue, 7 Jan 2025 15:51:30 +0100 Subject: [PATCH 57/93] fix(gh-actions): :bug: Fix appleboy/scp-action parameters Fix source parameter and target parameter --- .github/workflows/deploy-infra.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-infra.yml b/.github/workflows/deploy-infra.yml index 4836697..03aa4b5 100644 --- a/.github/workflows/deploy-infra.yml +++ b/.github/workflows/deploy-infra.yml @@ -33,8 +33,8 @@ jobs: host: ${{ secrets.DO_SSH_HOST_PRE }} username: ${{ secrets.DO_SSH_USER_PRE }} key: ${{ secrets.DO_SSH_KEY_PRE }} - source: .github/workflows/infra/docker/postgres-compose-pre.yml - target: /opt/summoners-sync/infra/docker/${{ env.COMPOSE_FILENAME }} + source: ".github/workflows/infra/docker/${{ env.COMPOSE_FILENAME }}" + target: /opt/summoners-sync/infra/docker/ rm: true # Deploy Infra From 745f5e077630a77633a443cdee3817f117e6d302 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Tue, 7 Jan 2025 15:56:37 +0100 Subject: [PATCH 58/93] fix(gh-actions): :bug: Added checkout Added checkout step so appleboy/scp-action can access the docker compose file --- .github/workflows/deploy-infra.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-infra.yml b/.github/workflows/deploy-infra.yml index 03aa4b5..edf47aa 100644 --- a/.github/workflows/deploy-infra.yml +++ b/.github/workflows/deploy-infra.yml @@ -23,9 +23,9 @@ jobs: echo "Generated filename: $filename" echo "COMPOSE_FILENAME=$filename" >> $GITHUB_ENV - - name: Debug secret name - run: | - echo "secret name : ${{ inputs.secret_name }}" + - name: Checkout Code + uses: actions/checkout@v4 + - name: Transfer Compose File to Server uses: appleboy/scp-action@v0.1.7 From 7f737938c943dab94ce5da71101554af4a22f626 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Tue, 7 Jan 2025 16:41:55 +0100 Subject: [PATCH 59/93] chore(gh-actions): Added debug command --- .github/workflows/deploy-infra.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-infra.yml b/.github/workflows/deploy-infra.yml index edf47aa..a2ce135 100644 --- a/.github/workflows/deploy-infra.yml +++ b/.github/workflows/deploy-infra.yml @@ -48,5 +48,5 @@ jobs: cd /opt/summoners-sync/infra/docker echo "${{ secrets[inputs.secret_name] }}" > .env - + ls -l docker-compose --env-file .env -f ${{ env.COMPOSE_FILENAME }} up -d \ No newline at end of file From 8272243a1055ace8d9c29e6a542259ed77960334 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Tue, 7 Jan 2025 16:49:14 +0100 Subject: [PATCH 60/93] refactor(gh-actions): :art: Moved folder infra to root. --- .github/workflows/deploy-infra.yml | 4 ++-- .../infra => infra}/docker/Summoners Sync Tables.sql | 0 .../workflows/infra => infra}/docker/postgres-compose-pre.yml | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename {.github/workflows/infra => infra}/docker/Summoners Sync Tables.sql (100%) rename {.github/workflows/infra => infra}/docker/postgres-compose-pre.yml (100%) diff --git a/.github/workflows/deploy-infra.yml b/.github/workflows/deploy-infra.yml index a2ce135..9b87f88 100644 --- a/.github/workflows/deploy-infra.yml +++ b/.github/workflows/deploy-infra.yml @@ -33,8 +33,8 @@ jobs: host: ${{ secrets.DO_SSH_HOST_PRE }} username: ${{ secrets.DO_SSH_USER_PRE }} key: ${{ secrets.DO_SSH_KEY_PRE }} - source: ".github/workflows/infra/docker/${{ env.COMPOSE_FILENAME }}" - target: /opt/summoners-sync/infra/docker/ + source: "infra/docker/${{ env.COMPOSE_FILENAME }}" + target: /opt/summoners-sync/ rm: true # Deploy Infra diff --git a/.github/workflows/infra/docker/Summoners Sync Tables.sql b/infra/docker/Summoners Sync Tables.sql similarity index 100% rename from .github/workflows/infra/docker/Summoners Sync Tables.sql rename to infra/docker/Summoners Sync Tables.sql diff --git a/.github/workflows/infra/docker/postgres-compose-pre.yml b/infra/docker/postgres-compose-pre.yml similarity index 100% rename from .github/workflows/infra/docker/postgres-compose-pre.yml rename to infra/docker/postgres-compose-pre.yml From 5e5720d71d0ae3e989f0cb9d5083433d8962c52e Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 26 Jan 2025 19:15:43 +0100 Subject: [PATCH 61/93] refactor(gh-actions): :recycle: Break actions in smaller ones. --- .github/workflows/deploy-chatbot.yml | 146 +++++++-------------------- .github/workflows/deploy-infra.yml | 26 ++++- .github/workflows/deploy-project.yml | 34 +++++++ .github/workflows/generate-token.yml | 18 ++++ .github/workflows/notify-user.yml | 31 ++++++ 5 files changed, 139 insertions(+), 116 deletions(-) create mode 100644 .github/workflows/deploy-project.yml create mode 100644 .github/workflows/generate-token.yml create mode 100644 .github/workflows/notify-user.yml diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 0585bb4..ba4b400 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -1,4 +1,4 @@ -name: Handle deployment commands in PR Comments +name: Deploy Chatbot on: issue_comment: @@ -6,129 +6,51 @@ on: - created jobs: - handle-deployment-on-pr-comment: + parse-command: runs-on: ubuntu-latest outputs: - artifact: ${{ steps.parse_command.outputs.infra }} - environment: ${{ steps.parse_command.outputs.environment }} - secret_name: ${{ steps.deploy-infra.outputs.secret_name}} + environment: ${{ steps.parse-command.outputs.environment }} + infra: ${{ steps.parse-command.outputs.infra }} + project: ${{ steps.parse-command.outputs.project }} - steps: - - uses: actions/checkout@v4 + steps: + - name: Checkout Repository + uses: actions/checkout@v4 - name: Parse Deployment Command uses: actions/github-script@v7 - id: parse_command + id: parse-command with: script: | const { default: parseDeployCommand } = - await import('${{ github.workspace }}/actions_scripts/parse_deployment_command.js'); - - parseDeployCommand({context, core}); - - - name: Get GH Zero Day Code APP token - if: ${{ !github.event.act }} - uses: actions/create-github-app-token@v1 - id: zdc-auth-app-token - with: - app-id: ${{ vars.ZDC_AUTH_APP_ID }} - private-key: ${{ secrets.ZDC_AUTH_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} - - - name: Notify the user - uses: actions/github-script@v7 - id: notify_user - with: - script: | - const environment = `${{ steps.parse_command.outputs.environment }}`; - const project = `${{ steps.parse_command.outputs.project }}`; - const infra = `${{ steps.parse_command.outputs.infra }}`; - - const { default: notifyUser } = - await import('${{ github.workspace }}/actions_scripts/notify_user.js'); - - return await notifyUser({github, context, core, environment, project, infra}); - - - name: Trigger Deployment Workflow - uses: actions/github-script@v7 - id: trigger_deployment_workflow - with: - github-token: ${{ steps.zdc-auth-app-token.outputs.token || github.token }} - script: | - const environment = `${{ steps.parse_command.outputs.environment }}`; - const project = `${{ steps.parse_command.outputs.project }}`; - const workflowId = `deploy-${environment}.yml`; - - let result = ""; - let details = ""; + await import(`${{ github.workspace }}/actions_scripts/parse_deployment_command.js`); - try { - await github.rest.actions.createWorkflowDispatch({ - owner: context.repo.owner, - repo: project, - workflow_id: workflowId, - ref: 'main', // TODO: Change branch to ref if pre, otherwise PRO should be only on main - }); - status = 'OK'; - details = 'succedeed'; - } catch (ex) { - console.log(`FAILED TO TRIGGER WORKFLOW:\n${ex}`); - status = 'ERR'; - details = `Failed to trigger the workflow ${workflowId} on repo: ${project}`; - } + parseDeployCommand({ context, core }); - // Return triggered details - return { - workflowId: workflowId, - status: status, - details: details, - }; + generate-token: + needs: parse-command + uses: zerodaycode/app-summoners-sync/.github/workflows/generate-token.yml@develop - - - name: Deploy Infra - id: deploy-infra - if: steps.parse_command.outputs.infra != '' - run: | - case "${{ steps.parse_command.outputs.infra }}" in - postgres) - echo "Deploying Postgres..." - ;; - redis) - echo "Deploying Redis..." - ;; - *) - echo "Unknown infra: ${{ steps.parse_command.outputs.infra }}" - exit 1 - ;; - esac - INFRA_UPPER=$(echo "${{steps.parse_command.outputs.infra }}" | tr 'a-z' 'A-Z') - ENV_UPPER=$(echo "${{ steps.parse_command.outputs.environment }}" | tr 'a-z' 'A-Z') - - secret_name="SS_${INFRA_UPPER}_${ENV_UPPER}" - - echo "Generated secret_name: $secret_name" - echo "SECRET_NAME=$secret_name" >> $GITHUB_OUTPUT - - - - name: Update Deployment Status - if: steps.parse_command.outputs.project != '' # TODO provisional ñapa while we don't add the remaining outputs - uses: actions/github-script@v7 - id: update-comment-with-deployment-status - with: - script: | - const steps = ${{ toJSON(steps) }}; - - const { default: updatePrComment } = - await import('${{ github.workspace }}/actions_scripts/update_pr_comment.js'); - - await updatePrComment(github, context, steps); + notify-user: + needs: generate-token + uses: zerodaycode/app-summoners-sync/.github/workflows/notify-user.yml@develop + with: + environment: ${{ needs.parse-command.outputs.environment }} + project: ${{ needs.parse-command.outputs.project }} + infra: ${{ needs.parse-command.outputs.infra }} + + trigger-deployment: + needs: notify-user + if: needs.parse-command.outputs.project != '' + uses: zerodaycode/app-summoners-sync/.github/workflows/trigger-deployment.yml@develop + with: + project: ${{ needs.parse-command.outputs.project }} + environment: ${{ needs.parse-command.outputs.environment }} - call-deploy-infra-artifact: - needs: handle-deployment-on-pr-comment + deploy-infra: + needs: notify-user + if: needs.parse-command.outputs.infra != '' uses: zerodaycode/app-summoners-sync/.github/workflows/deploy-infra.yml@develop with: - artifact: ${{ needs.handle-deployment-on-pr-comment.outputs.artifact }} - environment: ${{ needs.handle-deployment-on-pr-comment.outputs.environment }} - secret_name: ${{ needs.handle-deployment-on-pr-comment.outputs.secret_name }} - secrets: inherit - + artifact: ${{ needs.parse-command.outputs.infra }} + environment: ${{ needs.parse-command.outputs.environment }} diff --git a/.github/workflows/deploy-infra.yml b/.github/workflows/deploy-infra.yml index 9b87f88..9e69543 100644 --- a/.github/workflows/deploy-infra.yml +++ b/.github/workflows/deploy-infra.yml @@ -7,13 +7,20 @@ on: environment: required: true type: string - secret_name: - required: true - type: string jobs: deploy_infra_artifact: runs-on: ubuntu-latest steps: + - name: Validate Artifact + id: validate-artifact + run: | + case "${{ inputs.artifact }}" in + postgres|redis) + echo "Valid artifact: ${{ inputs.artifact }}" ;; + *) + echo "Unknown infra: ${{ inputs.artifact }}" + exit 1 ;; + esac - name: Build compose filename id: build-compose-filename run: | @@ -23,6 +30,17 @@ jobs: echo "Generated filename: $filename" echo "COMPOSE_FILENAME=$filename" >> $GITHUB_ENV + - name: Deploy Specific Infrastructure + id: generate-secret-name + run: | + INFRA_UPPER=$(echo "${{ inputs.artifact }}" | tr 'a-z' 'A-Z') + ENV_UPPER=$(echo "${{ inputs.environment }}" | tr 'a-z' 'A-Z') + + secret_name="SS_${INFRA_UPPER}_${ENV_UPPER}" + + echo "Generated secret_name: $secret_name" + echo "SECRET_NAME=$secret_name" >> $GITHUB_OUTPUT + - name: Checkout Code uses: actions/checkout@v4 @@ -47,6 +65,6 @@ jobs: script: | cd /opt/summoners-sync/infra/docker - echo "${{ secrets[inputs.secret_name] }}" > .env + echo "${{secrets[steps.generate-secret.outputs.SECRET_NAME] }}" > .env ls -l docker-compose --env-file .env -f ${{ env.COMPOSE_FILENAME }} up -d \ No newline at end of file diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml new file mode 100644 index 0000000..e98d072 --- /dev/null +++ b/.github/workflows/deploy-project.yml @@ -0,0 +1,34 @@ +name: Deploy Project Workflow + +on: + workflow_call: + inputs: + project: + required: true + type: string + environment: + required: true + type: string + +jobs: + trigger-deployment: + runs-on: ubuntu-latest + steps: + - name: Trigger Deployment Workflow + uses: actions/github-script@v7 + with: + script: | + const environment = `"${{ inputs.environment }}"`; + const project = `"${{ inputs.project }}"`; + const workflowId = `deploy-${environment}.yml`; + + try { + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: project, + workflow_id: workflowId, + ref: 'main', // Adjust this if necessary based on branch/ref logic + }); + } catch (error) { + core.setFailed(`Failed to trigger the workflow: ${error.message}`); + } \ No newline at end of file diff --git a/.github/workflows/generate-token.yml b/.github/workflows/generate-token.yml new file mode 100644 index 0000000..57a9e65 --- /dev/null +++ b/.github/workflows/generate-token.yml @@ -0,0 +1,18 @@ +name: Generate Token + +on: + workflow_call: + +jobs: + generate-token: + runs-on: ubuntu-latest + outputs: + token: ${{ steps.generate-token.outputs.token }} + steps: + - name: Generate GitHub App Token + uses: actions/create-github-app-token@v1 + id: generate-token + with: + app-id: ${{ vars.ZDC_AUTH_APP_ID }} + private-key: ${{ secrets.ZDC_AUTH_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} \ No newline at end of file diff --git a/.github/workflows/notify-user.yml b/.github/workflows/notify-user.yml new file mode 100644 index 0000000..5aa2031 --- /dev/null +++ b/.github/workflows/notify-user.yml @@ -0,0 +1,31 @@ +name: Notify User + +on: + workflow_call: + inputs: + environment: + required: true + type: string + project: + required: true + type: string + infra: + required: true + type: string + +jobs: + notify-user: + runs-on: ubuntu-latest + steps: + - name: Notify User + uses: actions/github-script@v7 + with: + script: | + const environment = `"${{ inputs.environment }}"`; + const project = `"${{ inputs.project }}"`; + const infra = `"${{ inputs.infra }}"`; + + const { default: notifyUser } = + await import(`${{ github.workspace }}/actions_scripts/notify_user.js`); + + return await notifyUser({github, context, core, environment, project, infra}); \ No newline at end of file From 6c32fcbf05f6b15d35c7ac9a0abfd03c03ee88a2 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 26 Jan 2025 19:21:41 +0100 Subject: [PATCH 62/93] fix(gh-actions): :bug: Fix workflow name --- .github/workflows/deploy-chatbot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index ba4b400..6000554 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -42,7 +42,7 @@ jobs: trigger-deployment: needs: notify-user if: needs.parse-command.outputs.project != '' - uses: zerodaycode/app-summoners-sync/.github/workflows/trigger-deployment.yml@develop + uses: zerodaycode/app-summoners-sync/.github/workflows/deploy-project.yml@develop with: project: ${{ needs.parse-command.outputs.project }} environment: ${{ needs.parse-command.outputs.environment }} From 67e954934bb64aae3121b218f2d088790c5b9e9f Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 26 Jan 2025 19:31:06 +0100 Subject: [PATCH 63/93] fix(gh-actions): :bug: Added secrets to generate token --- .github/workflows/deploy-chatbot.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 6000554..60a0b98 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -38,6 +38,7 @@ jobs: environment: ${{ needs.parse-command.outputs.environment }} project: ${{ needs.parse-command.outputs.project }} infra: ${{ needs.parse-command.outputs.infra }} + secrets: inherit trigger-deployment: needs: notify-user From 42e40253d127f701717fa9dcd213f7365ec737db Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 26 Jan 2025 20:10:08 +0100 Subject: [PATCH 64/93] fix(gh-actions): :bug: Add secrets for generate token --- .github/workflows/deploy-chatbot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 60a0b98..c87da78 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -30,6 +30,7 @@ jobs: generate-token: needs: parse-command uses: zerodaycode/app-summoners-sync/.github/workflows/generate-token.yml@develop + secrets: inherit notify-user: needs: generate-token @@ -38,7 +39,6 @@ jobs: environment: ${{ needs.parse-command.outputs.environment }} project: ${{ needs.parse-command.outputs.project }} infra: ${{ needs.parse-command.outputs.infra }} - secrets: inherit trigger-deployment: needs: notify-user From 2a9f80f9f1fa428d99ac7aee74bfeeb1188ae963 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 26 Jan 2025 20:15:05 +0100 Subject: [PATCH 65/93] fix(gh-actions): :bug: Add checkout on notify user --- .github/workflows/notify-user.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/notify-user.yml b/.github/workflows/notify-user.yml index 5aa2031..03f6cea 100644 --- a/.github/workflows/notify-user.yml +++ b/.github/workflows/notify-user.yml @@ -17,6 +17,10 @@ jobs: notify-user: runs-on: ubuntu-latest steps: + + - name: Checkout Code + uses: actions/checkout@v4 + - name: Notify User uses: actions/github-script@v7 with: From 4ea147aab939ac4ac37822b0db63200b316a4d59 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 26 Jan 2025 20:26:42 +0100 Subject: [PATCH 66/93] refactor(gh-actions): :recycle: Change id for parse step --- .github/workflows/deploy-chatbot.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index c87da78..4c91b72 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -9,9 +9,9 @@ jobs: parse-command: runs-on: ubuntu-latest outputs: - environment: ${{ steps.parse-command.outputs.environment }} - infra: ${{ steps.parse-command.outputs.infra }} - project: ${{ steps.parse-command.outputs.project }} + artifact: ${{ steps.parse-deploy-command.outputs.infra }} + environment: ${{ steps.parse-deploy-command.outputs.environment }} + project: ${{ steps.parse-parse-deploy-command.outputs.project }} steps: - name: Checkout Repository @@ -19,7 +19,7 @@ jobs: - name: Parse Deployment Command uses: actions/github-script@v7 - id: parse-command + id: parse-deploy-command with: script: | const { default: parseDeployCommand } = From f3e58cb613220205d7eaf9256d39f867286e9c01 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 26 Jan 2025 20:28:22 +0100 Subject: [PATCH 67/93] fix(gh-actions): :bug: Add secret inherit --- .github/workflows/deploy-chatbot.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 4c91b72..fe6272d 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -55,3 +55,4 @@ jobs: with: artifact: ${{ needs.parse-command.outputs.infra }} environment: ${{ needs.parse-command.outputs.environment }} + secrets: inherit From 4deaeb68ecc74254c0fe5de61119478b1d832bff Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 26 Jan 2025 20:41:34 +0100 Subject: [PATCH 68/93] fix(gh-actions): :bug: Fix infra variable --- .github/workflows/deploy-chatbot.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index fe6272d..e034bf5 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -38,7 +38,7 @@ jobs: with: environment: ${{ needs.parse-command.outputs.environment }} project: ${{ needs.parse-command.outputs.project }} - infra: ${{ needs.parse-command.outputs.infra }} + infra: ${{ needs.parse-command.outputs.artifact }} trigger-deployment: needs: notify-user @@ -50,9 +50,9 @@ jobs: deploy-infra: needs: notify-user - if: needs.parse-command.outputs.infra != '' + if: needs.parse-command.outputs.artifact != '' uses: zerodaycode/app-summoners-sync/.github/workflows/deploy-infra.yml@develop with: - artifact: ${{ needs.parse-command.outputs.infra }} + artifact: ${{ needs.parse-command.outputs.artifact }} environment: ${{ needs.parse-command.outputs.environment }} secrets: inherit From dc5293400410792d84ead045c327d28257b934f5 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 26 Jan 2025 21:34:43 +0100 Subject: [PATCH 69/93] chore(gh-actions): Add debug for variables --- .github/workflows/deploy-chatbot.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index e034bf5..a377cc1 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -26,6 +26,11 @@ jobs: await import(`${{ github.workspace }}/actions_scripts/parse_deployment_command.js`); parseDeployCommand({ context, core }); + - name: Debug Outputs + run: | + echo "Environment: ${{ steps.parse-deploy-command.outputs.environment }}" + echo "Project: ${{ steps.parse-deploy-command.outputs.project }}" + echo "Infra: ${{ steps.parse-deploy-command.outputs.infra }}" generate-token: needs: parse-command From 0e43d251d674a5cd91fde09bf5df9784d6f14d76 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 26 Jan 2025 21:40:58 +0100 Subject: [PATCH 70/93] chore(gh-actions): Testing needs change --- .github/workflows/deploy-chatbot.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index a377cc1..35dfdfc 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -38,7 +38,7 @@ jobs: secrets: inherit notify-user: - needs: generate-token + needs: parse-command uses: zerodaycode/app-summoners-sync/.github/workflows/notify-user.yml@develop with: environment: ${{ needs.parse-command.outputs.environment }} @@ -46,7 +46,7 @@ jobs: infra: ${{ needs.parse-command.outputs.artifact }} trigger-deployment: - needs: notify-user + needs: parse-command if: needs.parse-command.outputs.project != '' uses: zerodaycode/app-summoners-sync/.github/workflows/deploy-project.yml@develop with: @@ -54,7 +54,7 @@ jobs: environment: ${{ needs.parse-command.outputs.environment }} deploy-infra: - needs: notify-user + needs: parse-command if: needs.parse-command.outputs.artifact != '' uses: zerodaycode/app-summoners-sync/.github/workflows/deploy-infra.yml@develop with: From b678fb56eb23e548c02f4f56fa39b72c241e3d5b Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 26 Jan 2025 21:49:24 +0100 Subject: [PATCH 71/93] chore(gh-actions): :recycle: Change jobs needs --- .github/workflows/deploy-chatbot.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 35dfdfc..c9fc7fc 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -38,7 +38,7 @@ jobs: secrets: inherit notify-user: - needs: parse-command + needs: [parse-command, generate-token] uses: zerodaycode/app-summoners-sync/.github/workflows/notify-user.yml@develop with: environment: ${{ needs.parse-command.outputs.environment }} @@ -46,15 +46,16 @@ jobs: infra: ${{ needs.parse-command.outputs.artifact }} trigger-deployment: - needs: parse-command + needs: [parse-command, notify-user] if: needs.parse-command.outputs.project != '' uses: zerodaycode/app-summoners-sync/.github/workflows/deploy-project.yml@develop with: project: ${{ needs.parse-command.outputs.project }} environment: ${{ needs.parse-command.outputs.environment }} + secrets: inherit deploy-infra: - needs: parse-command + needs: [parse-command, notify-user] if: needs.parse-command.outputs.artifact != '' uses: zerodaycode/app-summoners-sync/.github/workflows/deploy-infra.yml@develop with: From 32820e26390f5e7dc441ba12879aeb9926628523 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Sun, 26 Jan 2025 22:02:33 +0100 Subject: [PATCH 72/93] fix(gh-actions): :bug: Fix project variable --- .github/workflows/deploy-chatbot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index c9fc7fc..0599d01 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -11,7 +11,7 @@ jobs: outputs: artifact: ${{ steps.parse-deploy-command.outputs.infra }} environment: ${{ steps.parse-deploy-command.outputs.environment }} - project: ${{ steps.parse-parse-deploy-command.outputs.project }} + project: ${{ steps.parse-deploy-command.outputs.project }} steps: - name: Checkout Repository From 60785fa4fc06f9f761930854bb1c9f1879dd818c Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Mon, 27 Jan 2025 19:26:19 +0100 Subject: [PATCH 73/93] chore: Normalize deployment workflows names --- .github/workflows/deploy-infra.yml | 2 ++ .github/workflows/deploy-project.yml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-infra.yml b/.github/workflows/deploy-infra.yml index 9e69543..16ce06c 100644 --- a/.github/workflows/deploy-infra.yml +++ b/.github/workflows/deploy-infra.yml @@ -1,3 +1,5 @@ +name: Deploy Infrastructure artifact + on: workflow_call: inputs: diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index e98d072..c10bdb5 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -1,4 +1,4 @@ -name: Deploy Project Workflow +name: Deploy Project on: workflow_call: @@ -11,7 +11,7 @@ on: type: string jobs: - trigger-deployment: + deploy_project_artifact: runs-on: ubuntu-latest steps: - name: Trigger Deployment Workflow From ddc175ae4128690d868211280a9331ba95b1f5b1 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Mon, 27 Jan 2025 19:51:17 +0100 Subject: [PATCH 74/93] chore(gh-actions): :ambulance: Tentative change for project deployment --- .github/workflows/deploy-chatbot.yml | 7 ++++--- .github/workflows/deploy-project.yml | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 0599d01..56de733 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -45,14 +45,15 @@ jobs: project: ${{ needs.parse-command.outputs.project }} infra: ${{ needs.parse-command.outputs.artifact }} - trigger-deployment: - needs: [parse-command, notify-user] + deploy-project: + needs: [parse-command, generate-token, notify-user] if: needs.parse-command.outputs.project != '' uses: zerodaycode/app-summoners-sync/.github/workflows/deploy-project.yml@develop with: project: ${{ needs.parse-command.outputs.project }} environment: ${{ needs.parse-command.outputs.environment }} - secrets: inherit + secrets: + zdc_token: ${{ needs.generate-token.outputs.token }} deploy-infra: needs: [parse-command, notify-user] diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index c10bdb5..03a16fb 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -9,6 +9,9 @@ on: environment: required: true type: string + secrets: + zdc_token: + required: true jobs: deploy_project_artifact: @@ -17,6 +20,7 @@ jobs: - name: Trigger Deployment Workflow uses: actions/github-script@v7 with: + github-token: ${{ secrets.zdc_token }} script: | const environment = `"${{ inputs.environment }}"`; const project = `"${{ inputs.project }}"`; From 4c93eaa767c4c3149777da2db0764144d7ae8d0d Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Mon, 27 Jan 2025 19:58:10 +0100 Subject: [PATCH 75/93] chore(gh-actions): :ambulance: Tentative changes for project deployment --- .github/workflows/deploy-chatbot.yml | 3 +-- .github/workflows/deploy-project.yml | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 56de733..9ad974c 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -52,8 +52,7 @@ jobs: with: project: ${{ needs.parse-command.outputs.project }} environment: ${{ needs.parse-command.outputs.environment }} - secrets: - zdc_token: ${{ needs.generate-token.outputs.token }} + token: ${{ needs.generate-token.outputs.token }} deploy-infra: needs: [parse-command, notify-user] diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index 03a16fb..e7d422c 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -9,9 +9,9 @@ on: environment: required: true type: string - secrets: - zdc_token: + token: required: true + type: string jobs: deploy_project_artifact: @@ -20,7 +20,7 @@ jobs: - name: Trigger Deployment Workflow uses: actions/github-script@v7 with: - github-token: ${{ secrets.zdc_token }} + github-token: ${{ inputs.token || github.token}} script: | const environment = `"${{ inputs.environment }}"`; const project = `"${{ inputs.project }}"`; From c87ae0884049c5f863c47cc656c88a8088083e87 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Mon, 27 Jan 2025 20:24:12 +0100 Subject: [PATCH 76/93] chore: Tentative changes for token --- .github/workflows/deploy-chatbot.yml | 1 + .github/workflows/deploy-project.yml | 2 +- .github/workflows/generate-token.yml | 10 +++++++--- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 9ad974c..0a586de 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -37,6 +37,7 @@ jobs: uses: zerodaycode/app-summoners-sync/.github/workflows/generate-token.yml@develop secrets: inherit + notify-user: needs: [parse-command, generate-token] uses: zerodaycode/app-summoners-sync/.github/workflows/notify-user.yml@develop diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index e7d422c..fefa717 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -20,7 +20,7 @@ jobs: - name: Trigger Deployment Workflow uses: actions/github-script@v7 with: - github-token: ${{ inputs.token || github.token}} + github-token: ${{ inputs.token }} script: | const environment = `"${{ inputs.environment }}"`; const project = `"${{ inputs.project }}"`; diff --git a/.github/workflows/generate-token.yml b/.github/workflows/generate-token.yml index 57a9e65..8e34c48 100644 --- a/.github/workflows/generate-token.yml +++ b/.github/workflows/generate-token.yml @@ -7,12 +7,16 @@ jobs: generate-token: runs-on: ubuntu-latest outputs: - token: ${{ steps.generate-token.outputs.token }} + token: ${{ steps.generate-zdc-token.outputs.token }} steps: - name: Generate GitHub App Token uses: actions/create-github-app-token@v1 - id: generate-token + id: generate-zdc-token with: app-id: ${{ vars.ZDC_AUTH_APP_ID }} private-key: ${{ secrets.ZDC_AUTH_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} \ No newline at end of file + owner: ${{ github.repository_owner }} + + - name: Debug Generated Token + run: | + echo "Generated Token: ${{ steps.generate-zdc-token.outputs.token }}" \ No newline at end of file From 8fe90f5d6db86517bf4411a27b2fcb9132795462 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Mon, 27 Jan 2025 20:29:44 +0100 Subject: [PATCH 77/93] chore: Tentative changes for token --- .github/workflows/deploy-chatbot.yml | 4 ++-- .github/workflows/deploy-project.yml | 4 ++-- .github/workflows/generate-token.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 0a586de..cdcc19a 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -37,7 +37,6 @@ jobs: uses: zerodaycode/app-summoners-sync/.github/workflows/generate-token.yml@develop secrets: inherit - notify-user: needs: [parse-command, generate-token] uses: zerodaycode/app-summoners-sync/.github/workflows/notify-user.yml@develop @@ -53,7 +52,8 @@ jobs: with: project: ${{ needs.parse-command.outputs.project }} environment: ${{ needs.parse-command.outputs.environment }} - token: ${{ needs.generate-token.outputs.token }} + secrets: + zdctoken: ${{ needs.generate-token.outputs.zdctoken }} deploy-infra: needs: [parse-command, notify-user] diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index fefa717..0d21806 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -9,7 +9,7 @@ on: environment: required: true type: string - token: + zdctoken: required: true type: string @@ -20,7 +20,7 @@ jobs: - name: Trigger Deployment Workflow uses: actions/github-script@v7 with: - github-token: ${{ inputs.token }} + github-token: ${{ inputs.zdctoken }} script: | const environment = `"${{ inputs.environment }}"`; const project = `"${{ inputs.project }}"`; diff --git a/.github/workflows/generate-token.yml b/.github/workflows/generate-token.yml index 8e34c48..ef102b0 100644 --- a/.github/workflows/generate-token.yml +++ b/.github/workflows/generate-token.yml @@ -7,7 +7,7 @@ jobs: generate-token: runs-on: ubuntu-latest outputs: - token: ${{ steps.generate-zdc-token.outputs.token }} + zdctoken: ${{ steps.generate-zdc-token.outputs.token }} steps: - name: Generate GitHub App Token uses: actions/create-github-app-token@v1 @@ -19,4 +19,4 @@ jobs: - name: Debug Generated Token run: | - echo "Generated Token: ${{ steps.generate-zdc-token.outputs.token }}" \ No newline at end of file + echo "Generated Token: ${{ steps.generate-zdc-token.outputs.token }}" \ No newline at end of file From 51d36ab7760d7d6be8716268a870379dbad8a44c Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Mon, 27 Jan 2025 20:31:42 +0100 Subject: [PATCH 78/93] chore: Tentative changes for token --- .github/workflows/deploy-project.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index 0d21806..52fcbdf 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -9,9 +9,7 @@ on: environment: required: true type: string - zdctoken: - required: true - type: string + jobs: deploy_project_artifact: From 7507f292d8174264a9b38e117125605dcd16b5c7 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Mon, 27 Jan 2025 20:33:29 +0100 Subject: [PATCH 79/93] chore: Tentative changes for token --- .github/workflows/deploy-project.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index 52fcbdf..2983231 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -9,7 +9,9 @@ on: environment: required: true type: string - + secrets: + personal_access_token: + required: true jobs: deploy_project_artifact: @@ -18,7 +20,7 @@ jobs: - name: Trigger Deployment Workflow uses: actions/github-script@v7 with: - github-token: ${{ inputs.zdctoken }} + github-token: ${{ secrets.zdctoken }} script: | const environment = `"${{ inputs.environment }}"`; const project = `"${{ inputs.project }}"`; From d7be080f3858a3f765b173e1be9f4841789b0933 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Mon, 27 Jan 2025 20:34:30 +0100 Subject: [PATCH 80/93] chore: Tentative changes for token --- .github/workflows/deploy-project.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index 2983231..70efcb9 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -10,7 +10,7 @@ on: required: true type: string secrets: - personal_access_token: + zdctoken: required: true jobs: From 699845f6e8d8728cc33fd758b4a1f651fa41b1a4 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Wed, 29 Jan 2025 18:35:12 +0100 Subject: [PATCH 81/93] chore: Encryption and decryption in token --- .github/workflows/deploy-chatbot.yml | 2 +- .github/workflows/deploy-project.yml | 12 ++++++++++-- .github/workflows/generate-token.yml | 9 ++++++--- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index cdcc19a..d0eb619 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -52,8 +52,8 @@ jobs: with: project: ${{ needs.parse-command.outputs.project }} environment: ${{ needs.parse-command.outputs.environment }} - secrets: zdctoken: ${{ needs.generate-token.outputs.zdctoken }} + secrets: inherit deploy-infra: needs: [parse-command, notify-user] diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index 70efcb9..96a6cea 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -9,18 +9,26 @@ on: environment: required: true type: string - secrets: zdctoken: required: true + type: string jobs: deploy_project_artifact: runs-on: ubuntu-latest steps: + - name: Decrypt ZDC Token + id: decrypt-token + run: | + ENCRYPTED_TOKEN="${{ secrets.zdctoken }}" + DECRYPTED_TOKEN=$(echo "$ENCRYPTED_TOKEN" | base64 -d | gpg --decrypt --quiet --batch --passphrase "${{ secrets.PASSPHRASE_ACTION_TOKEN }}") + echo "ZDCTOKEN=$DECRYPTED_TOKEN" >> $GITHUB_ENV + echo "::add-mask::$DECRYPTED_TOKEN" + - name: Trigger Deployment Workflow uses: actions/github-script@v7 with: - github-token: ${{ secrets.zdctoken }} + github-token: ${{ env.ZDCTOKEN }} script: | const environment = `"${{ inputs.environment }}"`; const project = `"${{ inputs.project }}"`; diff --git a/.github/workflows/generate-token.yml b/.github/workflows/generate-token.yml index ef102b0..40ba105 100644 --- a/.github/workflows/generate-token.yml +++ b/.github/workflows/generate-token.yml @@ -7,7 +7,7 @@ jobs: generate-token: runs-on: ubuntu-latest outputs: - zdctoken: ${{ steps.generate-zdc-token.outputs.token }} + zdctoken: ${{ steps.generate-zdc-token.outputs.encrypt-token }} steps: - name: Generate GitHub App Token uses: actions/create-github-app-token@v1 @@ -17,6 +17,9 @@ jobs: private-key: ${{ secrets.ZDC_AUTH_PRIVATE_KEY }} owner: ${{ github.repository_owner }} - - name: Debug Generated Token + - name: Encrypt and Encode Token + id: encrypt-token run: | - echo "Generated Token: ${{ steps.generate-zdc-token.outputs.token }}" \ No newline at end of file + TOKEN="${{ steps.generate-zdc-token.outputs.token }}" + ENCRYPTED_TOKEN=$(echo -n "$TOKEN" | gpg --symmetric --quiet --batch --passphrase "${{ secrets.PASSPHRASE_ACTION_TOKEN }}" | base64 -w0) + echo "zdctoken=$ENCRYPTED_TOKEN" >> $GITHUB_OUTPUT \ No newline at end of file From c2d0f690f4edb6b15c3aa6fcea2b3494fa63d6d7 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Wed, 29 Jan 2025 19:03:30 +0100 Subject: [PATCH 82/93] chore: Encryption and decryption in token --- .github/workflows/deploy-chatbot.yml | 5 +++-- .github/workflows/deploy-project.yml | 8 +++++--- .github/workflows/generate-token.yml | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index d0eb619..5edbf39 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -52,8 +52,9 @@ jobs: with: project: ${{ needs.parse-command.outputs.project }} environment: ${{ needs.parse-command.outputs.environment }} - zdctoken: ${{ needs.generate-token.outputs.zdctoken }} - secrets: inherit + secrets: + ZDC_TOKEN: ${{ needs.generate-token.outputs.zdctoken }} + PASSPHRASE_ACTION_TOKEN: ${{ secrets.PASSPHRASE_ACTION_TOKEN }} deploy-infra: needs: [parse-command, notify-user] diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index 96a6cea..3e4f1a6 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -9,9 +9,11 @@ on: environment: required: true type: string - zdctoken: + secrets: + ZDC_TOKEN: + required: true + PASSPHRASE_ACTION_TOKEN: required: true - type: string jobs: deploy_project_artifact: @@ -20,7 +22,7 @@ jobs: - name: Decrypt ZDC Token id: decrypt-token run: | - ENCRYPTED_TOKEN="${{ secrets.zdctoken }}" + ENCRYPTED_TOKEN="${{ secrets.ZDC_TOKEN }}" DECRYPTED_TOKEN=$(echo "$ENCRYPTED_TOKEN" | base64 -d | gpg --decrypt --quiet --batch --passphrase "${{ secrets.PASSPHRASE_ACTION_TOKEN }}") echo "ZDCTOKEN=$DECRYPTED_TOKEN" >> $GITHUB_ENV echo "::add-mask::$DECRYPTED_TOKEN" diff --git a/.github/workflows/generate-token.yml b/.github/workflows/generate-token.yml index 40ba105..49d78fa 100644 --- a/.github/workflows/generate-token.yml +++ b/.github/workflows/generate-token.yml @@ -7,7 +7,7 @@ jobs: generate-token: runs-on: ubuntu-latest outputs: - zdctoken: ${{ steps.generate-zdc-token.outputs.encrypt-token }} + ZDC_TOKEN: ${{ steps.encrypt-token.outputs.encrypt-token }} steps: - name: Generate GitHub App Token uses: actions/create-github-app-token@v1 @@ -22,4 +22,4 @@ jobs: run: | TOKEN="${{ steps.generate-zdc-token.outputs.token }}" ENCRYPTED_TOKEN=$(echo -n "$TOKEN" | gpg --symmetric --quiet --batch --passphrase "${{ secrets.PASSPHRASE_ACTION_TOKEN }}" | base64 -w0) - echo "zdctoken=$ENCRYPTED_TOKEN" >> $GITHUB_OUTPUT \ No newline at end of file + echo "ZDC_TOKEN=$ENCRYPTED_TOKEN" >> $GITHUB_OUTPUT \ No newline at end of file From 10373e2a9e25c00c832cac7413edd479808c370e Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Wed, 29 Jan 2025 20:31:47 +0100 Subject: [PATCH 83/93] fix(gh-actions): :bug: fix secret name --- .github/workflows/deploy-chatbot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 5edbf39..27d5da4 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -53,7 +53,7 @@ jobs: project: ${{ needs.parse-command.outputs.project }} environment: ${{ needs.parse-command.outputs.environment }} secrets: - ZDC_TOKEN: ${{ needs.generate-token.outputs.zdctoken }} + ZDC_TOKEN: ${{ needs.generate-token.outputs.ZDC_TOKEN }} PASSPHRASE_ACTION_TOKEN: ${{ secrets.PASSPHRASE_ACTION_TOKEN }} deploy-infra: From 1e2b58af02332d8c25965523999731c75e998e0d Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Wed, 29 Jan 2025 20:55:48 +0100 Subject: [PATCH 84/93] =?UTF-8?q?fix(gh-actions):=20=F0=9F=90=9B=20fix=20s?= =?UTF-8?q?ecret=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/generate-token.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/generate-token.yml b/.github/workflows/generate-token.yml index 49d78fa..ec8e208 100644 --- a/.github/workflows/generate-token.yml +++ b/.github/workflows/generate-token.yml @@ -7,7 +7,7 @@ jobs: generate-token: runs-on: ubuntu-latest outputs: - ZDC_TOKEN: ${{ steps.encrypt-token.outputs.encrypt-token }} + ZDC_TOKEN: ${{ steps.encrypt-token.outputs.ZDC_TOKEN }} steps: - name: Generate GitHub App Token uses: actions/create-github-app-token@v1 From 3562cfc38a0868a50c6f93df5ead1accc4c79836 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Wed, 29 Jan 2025 21:28:07 +0100 Subject: [PATCH 85/93] chore: Try to use token in inputs --- .github/workflows/deploy-chatbot.yml | 3 +-- .github/workflows/deploy-project.yml | 7 ++----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 27d5da4..7444dfd 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -52,9 +52,8 @@ jobs: with: project: ${{ needs.parse-command.outputs.project }} environment: ${{ needs.parse-command.outputs.environment }} - secrets: ZDC_TOKEN: ${{ needs.generate-token.outputs.ZDC_TOKEN }} - PASSPHRASE_ACTION_TOKEN: ${{ secrets.PASSPHRASE_ACTION_TOKEN }} + secrets: inherit deploy-infra: needs: [parse-command, notify-user] diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index 3e4f1a6..77331f4 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -9,11 +9,9 @@ on: environment: required: true type: string - secrets: ZDC_TOKEN: required: true - PASSPHRASE_ACTION_TOKEN: - required: true + type: string jobs: deploy_project_artifact: @@ -22,8 +20,7 @@ jobs: - name: Decrypt ZDC Token id: decrypt-token run: | - ENCRYPTED_TOKEN="${{ secrets.ZDC_TOKEN }}" - DECRYPTED_TOKEN=$(echo "$ENCRYPTED_TOKEN" | base64 -d | gpg --decrypt --quiet --batch --passphrase "${{ secrets.PASSPHRASE_ACTION_TOKEN }}") + DECRYPTED_TOKEN=$(echo "${{ inputs.ZDC_TOKEN }}" | base64 -d | gpg --decrypt --quiet --batch --passphrase "${{ secrets.PASSPHRASE_ACTION_TOKEN }}") echo "ZDCTOKEN=$DECRYPTED_TOKEN" >> $GITHUB_ENV echo "::add-mask::$DECRYPTED_TOKEN" From 8ec6920e385b3e550078dda0af549674074a1427 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Wed, 29 Jan 2025 21:41:30 +0100 Subject: [PATCH 86/93] chore: Tentative change --- .github/workflows/generate-token.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/generate-token.yml b/.github/workflows/generate-token.yml index ec8e208..a0d10e2 100644 --- a/.github/workflows/generate-token.yml +++ b/.github/workflows/generate-token.yml @@ -22,4 +22,4 @@ jobs: run: | TOKEN="${{ steps.generate-zdc-token.outputs.token }}" ENCRYPTED_TOKEN=$(echo -n "$TOKEN" | gpg --symmetric --quiet --batch --passphrase "${{ secrets.PASSPHRASE_ACTION_TOKEN }}" | base64 -w0) - echo "ZDC_TOKEN=$ENCRYPTED_TOKEN" >> $GITHUB_OUTPUT \ No newline at end of file + echo ZDC_TOKEN=$ENCRYPTED_TOKEN >> $GITHUB_OUTPUT \ No newline at end of file From bde52403d32ae2da3c56b45e2c55684f830f4700 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Wed, 29 Jan 2025 21:44:00 +0100 Subject: [PATCH 87/93] chore: Tentative change --- .github/workflows/deploy-chatbot.yml | 3 ++- .github/workflows/deploy-project.yml | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 7444dfd..27d5da4 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -52,8 +52,9 @@ jobs: with: project: ${{ needs.parse-command.outputs.project }} environment: ${{ needs.parse-command.outputs.environment }} + secrets: ZDC_TOKEN: ${{ needs.generate-token.outputs.ZDC_TOKEN }} - secrets: inherit + PASSPHRASE_ACTION_TOKEN: ${{ secrets.PASSPHRASE_ACTION_TOKEN }} deploy-infra: needs: [parse-command, notify-user] diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index 77331f4..3e4f1a6 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -9,9 +9,11 @@ on: environment: required: true type: string + secrets: ZDC_TOKEN: required: true - type: string + PASSPHRASE_ACTION_TOKEN: + required: true jobs: deploy_project_artifact: @@ -20,7 +22,8 @@ jobs: - name: Decrypt ZDC Token id: decrypt-token run: | - DECRYPTED_TOKEN=$(echo "${{ inputs.ZDC_TOKEN }}" | base64 -d | gpg --decrypt --quiet --batch --passphrase "${{ secrets.PASSPHRASE_ACTION_TOKEN }}") + ENCRYPTED_TOKEN="${{ secrets.ZDC_TOKEN }}" + DECRYPTED_TOKEN=$(echo "$ENCRYPTED_TOKEN" | base64 -d | gpg --decrypt --quiet --batch --passphrase "${{ secrets.PASSPHRASE_ACTION_TOKEN }}") echo "ZDCTOKEN=$DECRYPTED_TOKEN" >> $GITHUB_ENV echo "::add-mask::$DECRYPTED_TOKEN" From bcacc28febe8e4a9c3fe4858b60b5031ccf9b106 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Thu, 30 Jan 2025 16:03:14 +0100 Subject: [PATCH 88/93] feat(gh-actions): :rocket: Tentative change generate token as composite --- .github/actions/generate-token.yml | 17 +++++++++++++++++ .github/workflows/deploy-chatbot.yml | 12 ++---------- .github/workflows/deploy-project.yml | 18 +++++------------- .github/workflows/generate-token.yml | 25 ------------------------- 4 files changed, 24 insertions(+), 48 deletions(-) create mode 100644 .github/actions/generate-token.yml delete mode 100644 .github/workflows/generate-token.yml diff --git a/.github/actions/generate-token.yml b/.github/actions/generate-token.yml new file mode 100644 index 0000000..3ee7535 --- /dev/null +++ b/.github/actions/generate-token.yml @@ -0,0 +1,17 @@ +name: 'Generate GitHub App Token' +description: 'Generates a GitHub App token' +outputs: + token: + description: 'Generated GitHub App Token' + value: ${{ steps.generate-zdc-token.outputs.token }} + +runs: + using: "composite" + steps: + - name: Generate GitHub App Token + uses: actions/create-github-app-token@v1 + id: generate-zdc-token + with: + app-id: ${{ vars.ZDC_AUTH_APP_ID }} + private-key: ${{ secrets.ZDC_AUTH_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} \ No newline at end of file diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 27d5da4..0e5f960 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -32,13 +32,8 @@ jobs: echo "Project: ${{ steps.parse-deploy-command.outputs.project }}" echo "Infra: ${{ steps.parse-deploy-command.outputs.infra }}" - generate-token: - needs: parse-command - uses: zerodaycode/app-summoners-sync/.github/workflows/generate-token.yml@develop - secrets: inherit - notify-user: - needs: [parse-command, generate-token] + needs: [parse-command] uses: zerodaycode/app-summoners-sync/.github/workflows/notify-user.yml@develop with: environment: ${{ needs.parse-command.outputs.environment }} @@ -46,15 +41,12 @@ jobs: infra: ${{ needs.parse-command.outputs.artifact }} deploy-project: - needs: [parse-command, generate-token, notify-user] + needs: [parse-command, notify-user] if: needs.parse-command.outputs.project != '' uses: zerodaycode/app-summoners-sync/.github/workflows/deploy-project.yml@develop with: project: ${{ needs.parse-command.outputs.project }} environment: ${{ needs.parse-command.outputs.environment }} - secrets: - ZDC_TOKEN: ${{ needs.generate-token.outputs.ZDC_TOKEN }} - PASSPHRASE_ACTION_TOKEN: ${{ secrets.PASSPHRASE_ACTION_TOKEN }} deploy-infra: needs: [parse-command, notify-user] diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index 3e4f1a6..4ffebb4 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -9,28 +9,20 @@ on: environment: required: true type: string - secrets: - ZDC_TOKEN: - required: true - PASSPHRASE_ACTION_TOKEN: - required: true + jobs: deploy_project_artifact: runs-on: ubuntu-latest steps: - - name: Decrypt ZDC Token - id: decrypt-token - run: | - ENCRYPTED_TOKEN="${{ secrets.ZDC_TOKEN }}" - DECRYPTED_TOKEN=$(echo "$ENCRYPTED_TOKEN" | base64 -d | gpg --decrypt --quiet --batch --passphrase "${{ secrets.PASSPHRASE_ACTION_TOKEN }}") - echo "ZDCTOKEN=$DECRYPTED_TOKEN" >> $GITHUB_ENV - echo "::add-mask::$DECRYPTED_TOKEN" + - name: Generate Token + id: generate-token + uses: zerodaycode/app-summoners-sync/.github/actions/generate-token.yml@develop - name: Trigger Deployment Workflow uses: actions/github-script@v7 with: - github-token: ${{ env.ZDCTOKEN }} + github-token: ${{ steps.generate-token.outputs.token }} script: | const environment = `"${{ inputs.environment }}"`; const project = `"${{ inputs.project }}"`; diff --git a/.github/workflows/generate-token.yml b/.github/workflows/generate-token.yml deleted file mode 100644 index a0d10e2..0000000 --- a/.github/workflows/generate-token.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Generate Token - -on: - workflow_call: - -jobs: - generate-token: - runs-on: ubuntu-latest - outputs: - ZDC_TOKEN: ${{ steps.encrypt-token.outputs.ZDC_TOKEN }} - steps: - - name: Generate GitHub App Token - uses: actions/create-github-app-token@v1 - id: generate-zdc-token - with: - app-id: ${{ vars.ZDC_AUTH_APP_ID }} - private-key: ${{ secrets.ZDC_AUTH_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} - - - name: Encrypt and Encode Token - id: encrypt-token - run: | - TOKEN="${{ steps.generate-zdc-token.outputs.token }}" - ENCRYPTED_TOKEN=$(echo -n "$TOKEN" | gpg --symmetric --quiet --batch --passphrase "${{ secrets.PASSPHRASE_ACTION_TOKEN }}" | base64 -w0) - echo ZDC_TOKEN=$ENCRYPTED_TOKEN >> $GITHUB_OUTPUT \ No newline at end of file From 16e519177ad73626b92e3d68049deb6d5d64ddc8 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Thu, 30 Jan 2025 18:01:40 +0100 Subject: [PATCH 89/93] fix: composite folder and file naming --- .../actions/{generate-token.yml => generate-token/action.yml} | 0 .github/workflows/deploy-project.yml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename .github/actions/{generate-token.yml => generate-token/action.yml} (100%) diff --git a/.github/actions/generate-token.yml b/.github/actions/generate-token/action.yml similarity index 100% rename from .github/actions/generate-token.yml rename to .github/actions/generate-token/action.yml diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index 4ffebb4..7199a8b 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Generate Token id: generate-token - uses: zerodaycode/app-summoners-sync/.github/actions/generate-token.yml@develop + uses: zerodaycode/app-summoners-sync/.github/actions/generate-token@develop - name: Trigger Deployment Workflow uses: actions/github-script@v7 From c807a7c2d7e097e1ecd7536aa636f6843581654c Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Fri, 31 Jan 2025 14:45:29 +0100 Subject: [PATCH 90/93] =?UTF-8?q?feat(gh-actions):=20=F0=9F=9A=80=20Tentat?= =?UTF-8?q?ive=20change=20generate=20token=20as=20composite?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/actions/generate-token/action.yml | 12 ++++++++++-- .github/workflows/deploy-project.yml | 5 ++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/actions/generate-token/action.yml b/.github/actions/generate-token/action.yml index 3ee7535..99c0678 100644 --- a/.github/actions/generate-token/action.yml +++ b/.github/actions/generate-token/action.yml @@ -1,5 +1,13 @@ name: 'Generate GitHub App Token' description: 'Generates a GitHub App token' +inputs: + app-id: + description: 'GitHub App ID' + required: true + private-key: + description: 'GitHub App Private Key' + required: true + outputs: token: description: 'Generated GitHub App Token' @@ -12,6 +20,6 @@ runs: uses: actions/create-github-app-token@v1 id: generate-zdc-token with: - app-id: ${{ vars.ZDC_AUTH_APP_ID }} - private-key: ${{ secrets.ZDC_AUTH_PRIVATE_KEY }} + app-id: ${{ inputs.app-id }} + private-key: ${{ inputs.private-key }} owner: ${{ github.repository_owner }} \ No newline at end of file diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index 7199a8b..aab6a5d 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -18,7 +18,10 @@ jobs: - name: Generate Token id: generate-token uses: zerodaycode/app-summoners-sync/.github/actions/generate-token@develop - + with: + app-id: ${{ vars.ZDC_AUTH_APP_ID }} + private-key: ${{ secrets.ZDC_AUTH_PRIVATE_KEY }} + - name: Trigger Deployment Workflow uses: actions/github-script@v7 with: From 56b09d4046216807d22f3558a08e758bff4e3c59 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Fri, 31 Jan 2025 16:12:25 +0100 Subject: [PATCH 91/93] fix: I forgot the secrets inherit parameter. Oops ! --- .github/workflows/deploy-chatbot.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 0e5f960..2f3d8d0 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -47,7 +47,8 @@ jobs: with: project: ${{ needs.parse-command.outputs.project }} environment: ${{ needs.parse-command.outputs.environment }} - + secrets: inherit + deploy-infra: needs: [parse-command, notify-user] if: needs.parse-command.outputs.artifact != '' From 53234d64484daf2c9f0a43f67c054163b75af6b8 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Fri, 31 Jan 2025 16:41:18 +0100 Subject: [PATCH 92/93] fix: Remove extra quotes --- .github/workflows/deploy-project.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index aab6a5d..9672d90 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -27,8 +27,8 @@ jobs: with: github-token: ${{ steps.generate-token.outputs.token }} script: | - const environment = `"${{ inputs.environment }}"`; - const project = `"${{ inputs.project }}"`; + const environment = "${{ inputs.environment }}"; + const project = "${{ inputs.project }}"; const workflowId = `deploy-${environment}.yml`; try { From 928bc9cdfa28cda08bbabe815d67d5b1a05f0ce9 Mon Sep 17 00:00:00 2001 From: Gonzalo Busto Musi Date: Fri, 31 Jan 2025 17:08:37 +0100 Subject: [PATCH 93/93] chore(gh-actions): :construction_worker: Minor changes on job names --- .github/workflows/deploy-chatbot.yml | 6 +++++- .github/workflows/deploy-infra.yml | 4 ++-- .github/workflows/deploy-project.yml | 1 + .github/workflows/notify-user.yml | 1 + 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-chatbot.yml b/.github/workflows/deploy-chatbot.yml index 2f3d8d0..a1504f8 100644 --- a/.github/workflows/deploy-chatbot.yml +++ b/.github/workflows/deploy-chatbot.yml @@ -7,6 +7,7 @@ on: jobs: parse-command: + name: Parse command runs-on: ubuntu-latest outputs: artifact: ${{ steps.parse-deploy-command.outputs.infra }} @@ -33,6 +34,7 @@ jobs: echo "Infra: ${{ steps.parse-deploy-command.outputs.infra }}" notify-user: + name: Notify user needs: [parse-command] uses: zerodaycode/app-summoners-sync/.github/workflows/notify-user.yml@develop with: @@ -41,6 +43,7 @@ jobs: infra: ${{ needs.parse-command.outputs.artifact }} deploy-project: + name: Deploy project needs: [parse-command, notify-user] if: needs.parse-command.outputs.project != '' uses: zerodaycode/app-summoners-sync/.github/workflows/deploy-project.yml@develop @@ -48,8 +51,9 @@ jobs: project: ${{ needs.parse-command.outputs.project }} environment: ${{ needs.parse-command.outputs.environment }} secrets: inherit - + deploy-infra: + name: Deploy Infrastructure needs: [parse-command, notify-user] if: needs.parse-command.outputs.artifact != '' uses: zerodaycode/app-summoners-sync/.github/workflows/deploy-infra.yml@develop diff --git a/.github/workflows/deploy-infra.yml b/.github/workflows/deploy-infra.yml index 16ce06c..a30db77 100644 --- a/.github/workflows/deploy-infra.yml +++ b/.github/workflows/deploy-infra.yml @@ -11,6 +11,7 @@ on: type: string jobs: deploy_infra_artifact: + name: Deploy Infrastructure Artifact runs-on: ubuntu-latest steps: - name: Validate Artifact @@ -57,8 +58,7 @@ jobs: target: /opt/summoners-sync/ rm: true - # Deploy Infra - - name: Deploy Infra + - name: Run docker with env uses: appleboy/ssh-action@v1.2.0 with: host: ${{ secrets.DO_SSH_HOST_PRE }} diff --git a/.github/workflows/deploy-project.yml b/.github/workflows/deploy-project.yml index 9672d90..532c3b9 100644 --- a/.github/workflows/deploy-project.yml +++ b/.github/workflows/deploy-project.yml @@ -13,6 +13,7 @@ on: jobs: deploy_project_artifact: + name: Deploy Project Artifact runs-on: ubuntu-latest steps: - name: Generate Token diff --git a/.github/workflows/notify-user.yml b/.github/workflows/notify-user.yml index 03f6cea..7abdf43 100644 --- a/.github/workflows/notify-user.yml +++ b/.github/workflows/notify-user.yml @@ -15,6 +15,7 @@ on: jobs: notify-user: + name: Notify user runs-on: ubuntu-latest steps: