From 25e579a72bfa66332ee4e173e104ebb6f5e4118e Mon Sep 17 00:00:00 2001 From: Matthew Bystedt Date: Mon, 30 Dec 2024 16:46:01 -0800 Subject: [PATCH 1/3] feat: setup node js build template --- Dockerfile | 2 +- README.md | 10 +- generators/gh-maven-build/index.js | 2 +- generators/gh-nodejs-build/index.js | 329 +++++++++++ .../templates/build-intention.json | 29 + .../templates/build-intention.sh | 12 + .../templates/build-release.yaml | 124 +++++ .../templates/check-token.yaml | 37 ++ .../gh-nodejs-build/templates/deploy.yaml | 234 ++++++++ .../templates/deployment-intention.json | 59 ++ package-lock.json | 515 ++++++------------ package.json | 12 +- 12 files changed, 1006 insertions(+), 359 deletions(-) create mode 100644 generators/gh-nodejs-build/index.js create mode 100644 generators/gh-nodejs-build/templates/build-intention.json create mode 100644 generators/gh-nodejs-build/templates/build-intention.sh create mode 100644 generators/gh-nodejs-build/templates/build-release.yaml create mode 100644 generators/gh-nodejs-build/templates/check-token.yaml create mode 100644 generators/gh-nodejs-build/templates/deploy.yaml create mode 100644 generators/gh-nodejs-build/templates/deployment-intention.json diff --git a/Dockerfile b/Dockerfile index 80efea0..47edbee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:21-alpine +FROM node:22-alpine ARG APP=app ARG HOME=/home/node diff --git a/README.md b/README.md index c0acb56..e8163fe 100644 --- a/README.md +++ b/README.md @@ -15,13 +15,13 @@ You will need to install one of the following. Either can run the composer using * [Podman](https://podman.io) * [Docker](https://www.docker.com) -It is recommended that users running Windows install and run the command using node or use Podman. Docker has a known issue with modifying file permissions correctly on a mounted volumes. The tool needs to set the permission on things like bash scripts. As such, the commands will not run correctly on Windows with Docker. +It is recommended that Windows users install and run the command using Node.js or Podman. Docker has a known issue with correctly modifying file permissions on mounted volumes. Since the tool needs to set permissions for files like bash scripts, commands will not execute properly on Windows when using Docker. ## Run using a local install You will need to install node and clone this repository. You can checkout a version tag (vx.x.x) to run a specific release. -* [Node 20](https://nodejs.org/en) +* [Node 22](https://nodejs.org/en) The tool is build using [Yeoman](http://yeoman.io) which is a JavaScript library. You do not need to install Yoeman. @@ -73,6 +73,12 @@ The generator, gh-maven-build, generates the CI workflow and NR Broker intention The generated files will appear in your .github/workflows and .jenkins directories. +### Github Node.js Build: gh-nodejs-build + +The generator, gh-nodejs-build, generates the CI workflow and NR Broker intention files for building Node.js in GitHub. The workflow assume that your `package.json` has a `build` command and your build places the files in `./dist`. + +The generated files will appear in your .github/workflows and .jenkins directories. + ## Command Options ### Skip prompts (--promptless) diff --git a/generators/gh-maven-build/index.js b/generators/gh-maven-build/index.js index 8752013..7afcd5e 100644 --- a/generators/gh-maven-build/index.js +++ b/generators/gh-maven-build/index.js @@ -112,7 +112,7 @@ export default class extends Generator { { type: 'checkbox', name: 'skip', - message: `Do not prompt for values set in ${BACKSTAGE_FILENAME}:`, + message: `Skip prompts for values found in Backstage file (${BACKSTAGE_FILENAME}):`, choices: ['yes', 'no'], default: 'yes', store: true, diff --git a/generators/gh-nodejs-build/index.js b/generators/gh-nodejs-build/index.js new file mode 100644 index 0000000..44c4567 --- /dev/null +++ b/generators/gh-nodejs-build/index.js @@ -0,0 +1,329 @@ +'use strict'; +import * as fs from 'fs'; +import Generator from 'yeoman-generator'; +import yosay from 'yosay'; +import chalk from 'chalk'; +import { Document, parseDocument } from 'yaml'; +import { + BACKSTAGE_FILENAME, + pathToProps, + extractFromYaml, + generateSetAnswerPropPredicate, + writePropToPath, +} from '../util/yaml.js'; + +/** + * Generate the CI workflow and NR Broker intention files needed for Java/Tomcat Maven builds in GitHub + */ +export default class extends Generator { + constructor(args, opts) { + super(args, opts); + + this.option('promptless', { + type: String, + required: false, + description: 'Run headless with no user prompts', + }); + } + + async initializing() { + const backstagePath = this.destinationPath(BACKSTAGE_FILENAME); + if (fs.existsSync(backstagePath)) { + const backstageYaml = fs.readFileSync(backstagePath, 'utf8'); + this.backstageDoc = parseDocument(backstageYaml); + } else { + this.backstageDoc = new Document(); + } + } + + async prompting() { + const promptless = !!this.options.promptless; + this.answers = extractFromYaml(this.backstageDoc, pathToProps); + console.log(this.answers); + + if (!promptless) { + this.log( + yosay( + 'Welcome to the GitHub workflow and NR Broker intention file generator!', + ), + ); + + this.log(chalk.bold('Usage')); + this.log(''); + this.log( + ' ' + + chalk.bold('Project: ') + + chalk.dim( + 'Lowercase kebab-case name that uniquely identifies the project', + ), + ); + this.log(' ' + chalk.dim('Example: super-project')); + this.log( + ' ' + + chalk.bold('Service: ') + + chalk.dim( + 'Lowercase kebab-case name that uniquely indentifies the service', + ), + ); + this.log( + ' ' + + chalk.dim( + 'Should start with project, have an optional descriptor and end with an artifact identifier', + ), + ); + this.log( + ' ' + chalk.dim('Example: super-project-backend-war'), + ); + this.log( + ' ' + + chalk.bold('Client ID: ') + + chalk.dim( + 'The client id of the Broker account to use. Leave blank to use manually set BROKER_JWT secret.', + ), + ); + this.log( + ' ' + + chalk.bold('Artifactory: ') + + chalk.dim('The OCP Artifactory namespace this will be published to'), + ); + this.log( + ' ' + + chalk.bold('Root: ') + + chalk.dim( + "The path to where your build is located relative to the repository's root", + ), + ); + this.log( + ' ' + + chalk.bold('GitHub Owner with repo path: ') + + chalk.dim( + 'The Github owner with repo path (e.g. bcgov-nr/edqa-war) ', + ), + ); + this.log(''); + + this.log(chalk.bold('Prompts')); + this.log(''); + } + + const backstageAnswer = promptless + ? { skip: true } + : await this.prompt([ + { + type: 'checkbox', + name: 'skip', + message: `Skip prompts for values found in Backstage file (${BACKSTAGE_FILENAME}):`, + choices: ['yes', 'no'], + default: 'yes', + store: true, + }, + ]); + + this.answers = { + ...this.answers, + ...(await this.prompt( + [ + { + type: 'input', + name: 'projectName', + message: 'Project:', + store: true, + }, + { + type: 'input', + name: 'serviceName', + message: 'Service:', + store: true, + }, + { + type: 'input', + name: 'clientId', + message: 'Client ID:', + default: '', + store: true, + }, + { + type: 'input', + name: 'unitTestsPath', + message: 'Path to unit tests (./.github/workflows/test.yaml):', + default: '', + store: true, + }, + { + type: 'confirm', + name: 'gitHubPackages', + message: 'Publish to GitHub Packages:', + default: false, + store: true, + }, + { + type: 'input', + name: 'gitHubOwnerPack', + message: 'GitHub Owner with repo path (e.g. bcgov-nr/results-war):', + store: true, + when: (answers) => answers.gitHubPackages, + }, + { + type: 'input', + name: 'artifactoryProject', + message: 'Artifactory:', + default: 'cc20', + store: true, + when: (answers) => !answers.gitHubPackages, + }, + { + type: 'input', + name: 'artifactoryPackageType', + message: 'Artifactory Package Type (maven, ivy, npm):', + default: 'maven', + store: true, + when: (answers) => !answers.gitHubPackages, + }, + { + type: 'confirm', + name: 'deployOnPrem', + message: 'Deploy on-prem:', + default: false, + store: true, + }, + { + type: 'input', + name: 'playbookPath', + message: 'Playbook path:', + default: 'playbooks', + store: true, + when: (answers) => answers.deployOnPrem, + }, + { + type: 'input', + name: 'tomcatContext', + message: 'Tomcat Context (e.g. ext#results):', + store: true, + when: (answers) => answers.deployOnPrem, + }, + { + type: 'confirm', + name: 'useAltAppDirName', + message: 'Use alternative webapp directory:', + default: false, + store: true, + when: (answers) => answers.deployOnPrem, + }, + { + type: 'input', + name: 'altAppDirName', + message: 'Alternative webapp directory name:', + store: true, + when: (answers) => answers.useAltAppDirName, + }, + { + type: 'confirm', + name: 'addWebadeConfig', + message: 'Add Webade configuration:', + default: false, + store: true, + when: (answers) => answers.deployOnPrem, + }, + ].filter( + generateSetAnswerPropPredicate( + this.answers, + backstageAnswer.skip === 'yes', + ), + ), + )), + }; + } + + async configuring() { + // this.config.save(); + } + + // Generate GitHub workflows and NR Broker intention files + writingWorkflow() { + const brokerJwt = this.answers.clientId.trim() + ? `broker-jwt:${this.answers.clientId.trim()}`.replace( + /[^a-zA-Z0-9_]/g, + '_', + ) + : 'BROKER_JWT'; + this.fs.copyTpl( + this.templatePath('build-release.yaml'), + this.destinationPath('.github/workflows/build-release.yaml'), + { + projectName: this.answers.projectName, + serviceName: this.answers.serviceName, + brokerJwt, + artifactoryProject: this.answers.artifactoryProject, + pomRoot: this.answers.pomRoot, + unitTestsPath: this.answers.unitTestsPath, + gitHubPackages: this.answers.gitHubPackages, + artifactoryPackageType: this.answers.artifactoryPackageType, + gitHubOwnerPack: this.answers.gitHubOwnerPack, + }, + ); + this.fs.copyTpl( + this.templatePath('build-intention.json'), + this.destinationPath('.github/workflows/build-intention.json'), + { + projectName: this.answers.projectName, + serviceName: this.answers.serviceName, + }, + ); + this.fs.copyTpl( + this.templatePath('build-intention.sh'), + this.destinationPath('.github/workflows/build-intention.sh'), + ); + this.fs.copyTpl( + this.templatePath('check-token.yaml'), + this.destinationPath('.github/workflows/check-token.yaml'), + ); + if (this.answers.deployOnPrem) { + this.fs.copyTpl( + this.templatePath('deploy.yaml'), + this.destinationPath('.github/workflows/deploy.yaml'), + { + projectName: this.answers.projectName, + serviceName: this.answers.serviceName, + brokerJwt, + artifactoryProject: this.answers.artifactoryProject, + pomRoot: this.answers.pomRoot, + gitHubPackages: this.answers.gitHubPackages, + artifactoryPackageType: this.answers.artifactoryPackageType, + gitHubOwnerPack: this.answers.gitHubOwnerPack, + }, + ); + this.fs.copyTpl( + this.templatePath('deployment-intention.json'), + this.destinationPath('.jenkins/deployment-intention.json'), + { + projectName: this.answers.projectName, + serviceName: this.answers.serviceName, + }, + ); + const playbook_args = [ + this.answers.projectName, + this.answers.serviceName, + this.answers.playbookPath, + this.answers.tomcatContext, + this.answers.altAppDirName, + ]; + const playbook_options = { + addWebadeConfig: this.answers.addWebadeConfig, + altAppDirName: this.answers.altAppDirName, + }; + this.composeWith( + 'nr-repository-composer:pd-ansible-playbook', + playbook_args, + playbook_options, + ); + } + } + + writingBackstage() { + writePropToPath(this.backstageDoc, pathToProps, this.answers); + this.fs.write( + this.destinationPath(BACKSTAGE_FILENAME), + this.backstageDoc.toString(), + ); + } +} diff --git a/generators/gh-nodejs-build/templates/build-intention.json b/generators/gh-nodejs-build/templates/build-intention.json new file mode 100644 index 0000000..72fd495 --- /dev/null +++ b/generators/gh-nodejs-build/templates/build-intention.json @@ -0,0 +1,29 @@ +{ + "event": { + "provider": "github-action-build", + "reason": "Job triggered", + "url": "JOB_URL" + }, + "actions": [ + { + "action": "package-build", + "id": "build", + "provision": [], + "service": { + "project": "<%= projectName %>", + "name": "<%= serviceName %>", + "environment": "tools" + }, + "package": { + "version": "", + "buildVersion": "", + "buildNumber": 0, + "name": "<%= serviceName %>", + "type": "application/vnd.oci.image.layer.v1.tar" + } + } + ], + "user": { + "name": "github@internal" + } +} \ No newline at end of file diff --git a/generators/gh-nodejs-build/templates/build-intention.sh b/generators/gh-nodejs-build/templates/build-intention.sh new file mode 100644 index 0000000..afe1166 --- /dev/null +++ b/generators/gh-nodejs-build/templates/build-intention.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +echo "===> Create Intention" +# Create intention +cat ./.github/workflows/build-intention.json | jq "\ + .event.reason=\"${EVENT_REASON}\" | \ + .event.url=\"https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}\" | \ + (.actions[] | select(.id == \"build\") .package.version) |= \"${PACKAGE_VERSION}\" | \ + (.actions[] | select(.id == \"build\") .package.buildGuid) |= \"${PACKAGE_BUILD_GUID}\" | \ + (.actions[] | select(.id == \"build\") .package.buildVersion) |= \"${PACKAGE_BUILD_VERSION}\" | \ + (.actions[] | select(.id == \"build\") .package.buildNumber) |= ${PACKAGE_BUILD_NUMBER} \ + " > intention.json \ No newline at end of file diff --git a/generators/gh-nodejs-build/templates/build-release.yaml b/generators/gh-nodejs-build/templates/build-release.yaml new file mode 100644 index 0000000..79659c5 --- /dev/null +++ b/generators/gh-nodejs-build/templates/build-release.yaml @@ -0,0 +1,124 @@ +name: Build and release + +on: + push: + tags: + - 'v*' + pull_request: + branches: + - main + workflow_dispatch: + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + BROKER_URL: https://broker.io.nrs.gov.bc.ca + BROKER_JWT: ${{ secrets.<%= brokerJwt %> }} + SERVICE_PROJECT: <%= projectName %> + SERVICE_NAME: <%= serviceName %> + +jobs: + check_token_expiration: + uses: ./.github/workflows/check-token.yaml + secrets: + token: ${{ secrets.<%= brokerJwt %> }} +<% if (unitTestsPath) { -%> + test: + name: Test + if: ${{ ! startsWith(github.ref, 'refs/tags/v') }} + uses: <%= unitTestsPath %> +<% } -%> + build-release: + name: Build and release + runs-on: ubuntu-latest +<% if (unitTestsPath) { -%> + needs: [check_token_expiration, test] +<% } else { -%> + needs: check_token_expiration +<% } -%> + permissions: + contents: read + packages: write + outputs: + project_version: ${{ steps.set-build-output-parameters.outputs.project_version }} + intention_id: ${{ steps.set-intention-id.outputs.intention_id }} + branch: $${{ steps.set-branch.outputs.branch }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + ref: ${{ github.ref }} + - name: Setup ORAS + uses: oras-project/setup-oras@v1 + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: 'npm' + - name: Set branch + id: set-branch + if: ${{ ! startsWith(github.ref, 'refs/tags/v') }} + run: | + if [[ ${{ startsWith(github.ref, 'refs/heads/') }} = true ]]; then + echo "branch=${{ github.ref_name }}" >> "$GITHUB_OUTPUT" + fi + if [[ ${{ startsWith(github.ref, 'refs/pull/') }} = true ]]; then + echo "branch=${{ github.head_ref }}" >> "$GITHUB_OUTPUT" + fi + - name: Set build output parameters + id: set-build-output-parameters + run: | + echo "project_version=1.0.0" >> $GITHUB_OUTPUT + echo "git_commit=$(git rev-parse --verify HEAD)" >> $GITHUB_OUTPUT + echo "build_guid=uuid::$(uuidgen)" >> $GITHUB_OUTPUT + - name: Build intention + run: sh ./.github/workflows/build-intention.sh + env: + EVENT_REASON: Build ${{ github.ref_name }} + GITHUB_REPOSITORY: ${{ github.repository}} + GITHUB_RUN_ID: ${{ github.run_id}} + PACKAGE_BUILD_GUID: ${{ steps.set-build-output-parameters.outputs.build_guid }} + PACKAGE_BUILD_NUMBER: ${{ github.run_number }} + PACKAGE_BUILD_VERSION: ${{ steps.set-build-output-parameters.outputs.git_commit }} + PACKAGE_VERSION: ${{ steps.set-build-output-parameters.outputs.project_version }} + - name: Open intention + uses: bcgov-nr/action-broker-intention-open@v2 + with: + broker_jwt: ${{ secrets.<%= brokerJwt %> }} + intention_path: intention.json + quickstart: true + - name: Set intention ID for deployment job + id: set-intention-id + run: | + echo "intention_id=${INTENTION_ID}" >> $GITHUB_OUTPUT + env: + INTENTION_ID: ${{ env.INTENTION_ID }} + - name: npm ci + run: npm ci + - name: Build artifact + run: npm run build --if-present + - name: Push build + run: | + oras push ghcr.io/${{ github.repository_owner }}/${{ github.repository}}:${PROJECT_VERSION} dist + MANIFEST=$(oras manifest fetch ghcr.io/${{ github.repository_owner }}/${{ github.repository}}:${PROJECT_VERSION}) + echo "artifact_sha256=$(echo $MANIFEST | jq -r '.layers[0].digest')" >> $GITHUB_OUTPUT + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PROJECT_VERSION: ${{ steps.set-build-output-parameters.outputs.project_version }} + - name: Send build info + run: | + curl -s POST ${{ env.BROKER_URL }}/v1/intention/action/patch \ + -H 'Content-Type: application/json' \ + -H 'X-Broker-Token: '"${BUILD_TOKEN}"'' \ + -d '{"package":{"checksum": "sha256:'${ARTIFACT_SHA256}'"}}' + env: + ARTIFACT_SHA256: ${{ steps.publish-artifact.outputs.artifact_sha256 }} + BUILD_TOKEN: ${{ env.ACTION_TOKEN_BUILD }} + - name: Close intention + uses: bcgov-nr/action-broker-intention-close@v1 + with: + intention_token: ${{ env.INTENTION_TOKEN }} diff --git a/generators/gh-nodejs-build/templates/check-token.yaml b/generators/gh-nodejs-build/templates/check-token.yaml new file mode 100644 index 0000000..6b09c80 --- /dev/null +++ b/generators/gh-nodejs-build/templates/check-token.yaml @@ -0,0 +1,37 @@ +name: Check token expiration + +on: + workflow_call: + inputs: + url: + description: "The Broker URL" + default: https://broker.io.nrs.gov.bc.ca + type: string + secrets: + token: + description: "The Broker token" + required: true + +jobs: + check-jwt: + runs-on: ubuntu-latest + + steps: + - name: Check token expiration + shell: bash + run: | + RESPONSE_CODE=$(curl -o /dev/null -s -w "%{http_code}" -X 'GET' \ + ${{ inputs.url }}/v1/health/token-check \ + -H 'accept: */*' \ + -H 'Authorization: Bearer '"${{ secrets.token }}"'' \ + ) + + if [ "$RESPONSE_CODE" -eq 401 ]; then + echo "Unauthorized (401)" + exit 1 + elif [ "$RESPONSE_CODE" -eq 403 ]; then + echo "Invalid JWT: Block list has match" + exit 1 + else + echo "Response code: $RESPONSE_CODE" + fi \ No newline at end of file diff --git a/generators/gh-nodejs-build/templates/deploy.yaml b/generators/gh-nodejs-build/templates/deploy.yaml new file mode 100644 index 0000000..49abdfc --- /dev/null +++ b/generators/gh-nodejs-build/templates/deploy.yaml @@ -0,0 +1,234 @@ +name: Deploy + +on: + workflow_dispatch: + inputs: + config_branch: + description: 'Use branch for testing configuration changes' + required: false + type: string + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + SERVICE_PROJECT: <%= projectName %> + SERVICE_NAME: <%= serviceName %> + JOB: buildByToken/buildWithParameters?job=<%= projectName %>/<%= serviceName %> + URL: https://cd.io.nrs.gov.bc.ca +<% if (gitHubPackages) { -%> + PACKAGE_REPO: https://maven.pkg.github.com/<%= gitHubOwnerPack %> +<% } else { -%> + PACKAGE_REPO: https://artifacts.developer.gov.bc.ca/artifactory/<%= artifactoryProject %>-<%= projectName %>-<%= artifactoryPackageType %>-local +<% } -%> + +jobs: + check_token_expiration: + uses: ./.github/workflows/check-token.yaml + secrets: + token: ${{ secrets.<%= brokerJwt %> }} + deploy-build: + name: Deploy development version + if: ${{ ! startsWith(github.ref, 'refs/tags/') }} + runs-on: ubuntu-latest + needs: check_token_expiration + outputs: + project_version: ${{ steps.set-build-output.outputs.project_version }} + build_guid: ${{ steps.set-build-output.outputs.build_guid }} + build_number: ${{ steps.set-build-output.outputs.build_number }} + artifact_name: ${{ steps.set-build-output.outputs.artifact_name }} + artifact_sha256: ${{ steps.set-build-output.outputs.artifact_sha256 }} + download_url: ${{ steps.set-download-url.outputs.download_url }} + steps: + - name: Set build output + id: set-build-output + run: | + RESPONSE=$(curl -s -X 'POST' \ + "${BROKER_URL}/v1/intention/search?where=%7B%22actions.action%22%3A%22package-build%22%2C%22actions.service.project%22%3A%22${SERVICE_PROJECT}%22%2C%22actions.service.name%22%3A%22${SERVICE_NAME}%22%2C%22actions.package.buildVersion%22%3A%22${GITHUB_SHA}%22%7D&offset=0&limit=1" \ + -H 'accept: application/json' \ + -H 'Authorization: Bearer '"${BROKER_JWT}"'' \ + -d '') + if echo "$RESPONSE" | jq -e '.statusCode == 401' > /dev/null; then + echo "Status code is 401. This indicates an authorization error." + echo "Please check if your Broker Token is valid. Teams can generate a new one in Broker if needed." + echo "Link: https://broker.io.nrs.gov.bc.ca/browse/brokerAccount" + echo "Exiting..." + exit 1 + fi + echo "project_version=$(echo ${RESPONSE} | jq -r '.data[].actions[].package.version')" >> $GITHUB_OUTPUT + echo "build_guid=$(echo ${RESPONSE} | jq -r '.data[].id')" >> $GITHUB_OUTPUT + echo "build_number=$(echo ${RESPONSE} | jq -r '.data[].actions[].package.buildNumber')" >> $GITHUB_OUTPUT + echo "artifact_name=$(echo ${RESPONSE} | jq -r '.data[].actions[].artifacts[].name')" >> $GITHUB_OUTPUT + artifact_checksum=$(echo ${RESPONSE} | jq -r '.data[].actions[].artifacts[].checksum') + echo "artifact_sha256=${artifact_checksum#sha256:}" >> $GITHUB_OUTPUT + env: + BROKER_URL: https://broker.io.nrs.gov.bc.ca + BROKER_JWT: ${{ secrets.<%= brokerJwt %> }} + SERVICE_PROJECT: ${{ env.SERVICE_PROJECT }} + SERVICE_NAME: ${{ env.SERVICE_NAME }} + GITHUB_SHA: ${{ github.sha }} + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + ref: ${{ github.ref }} + - name: Set up Java + uses: actions/setup-java@v4 + with: + java-version: '8' + distribution: 'temurin' + cache: maven + - name: Set download URL + id: set-download-url +<% if (gitHubPackages) { -%> + run: | + sudo apt-get -qq install libxml2-utils + GROUP_ID=$(mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout --file <%= pomRoot %>pom.xml) + GROUP_ID_PATH="${GROUP_ID//.//}" + PACKAGE_TYPE=$(mvn help:evaluate -Dexpression=project.packaging -q -DforceStdout --file <%= pomRoot %>pom.xml) + curl -LO "${PACKAGE_REPO}/${GROUP_ID_PATH}/${SERVICE_NAME}/${PROJECT_VERSION}/maven-metadata.xml" -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" + TIMESTAMP=$(xmllint --xpath '//metadata/versioning/snapshot/timestamp/text()' maven-metadata.xml) + BUILD_NUMBER=$(xmllint --xpath '//metadata/versioning/snapshot/buildNumber/text()' maven-metadata.xml) + SNAPSHOT_VERSION="${PROJECT_VERSION//SNAPSHOT/$TIMESTAMP-$BUILD_NUMBER}" + ARTIFACT_NAME="${SERVICE_NAME}-${SNAPSHOT_VERSION}.${PACKAGE_TYPE}" + DOWNLOAD_URL="${PACKAGE_REPO}/${GROUP_ID_PATH}/${SERVICE_NAME}/${PROJECT_VERSION}/${ARTIFACT_NAME}" + echo "${DOWNLOAD_URL}" + echo "download_url=$(echo ${DOWNLOAD_URL})" >> $GITHUB_OUTPUT +<% } else { -%> + run: | + sudo apt-get -qq install libxml2-utils + GROUP_ID=$(mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout --file <%= pomRoot %>pom.xml) + GROUP_ID_PATH="${GROUP_ID//.//}" + PACKAGE_TYPE=$(mvn help:evaluate -Dexpression=project.packaging -q -DforceStdout --file <%= pomRoot %>pom.xml) + SNAPSHOT_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout --file <%= pomRoot %>pom.xml) + ARTIFACT_NAME="${SERVICE_NAME}-${SNAPSHOT_VERSION}.${PACKAGE_TYPE}" + DOWNLOAD_URL="${PACKAGE_REPO}/${GROUP_ID_PATH}/${SERVICE_NAME}/${PROJECT_VERSION}/${ARTIFACT_NAME}" + echo "${DOWNLOAD_URL}" + echo "download_url=$(echo ${DOWNLOAD_URL})" >> $GITHUB_OUTPUT +<% } -%> + env: + SERVICE_NAME: ${{ env.SERVICE_NAME }} + PROJECT_VERSION: ${{ steps.set-build-output.outputs.project_version }} + PACKAGE_REPO: ${{ env.PACKAGE_REPO }} + deploy-tag: + name: Deploy release version + if: ${{ startsWith(github.ref, 'refs/tags/') }} + runs-on: ubuntu-latest + needs: check_token_expiration + outputs: + project_version: ${{ steps.set-tag-output.outputs.project_version }} + build_guid: ${{ steps.set-tag-output.outputs.build_guid }} + build_number: ${{ steps.set-tag-output.outputs.build_number }} + artifact_name: ${{ steps.set-tag-output.outputs.artifact_name }} + artifact_sha256: ${{ steps.set-tag-output.outputs.artifact_sha256 }} + download_url: ${{ steps.set-download-url.outputs.download_url }} + steps: + - name: Set tag output + id: set-tag-output + run: | + TAG=${{ github.ref_name }} + PROJECT_VERSION=${TAG#v} + RESPONSE=$(curl -s -X 'POST' \ + "${BROKER_URL}/v1/intention/search?where=%7B%22actions.action%22%3A%22package-build%22%2C%22actions.service.project%22%3A%22${SERVICE_PROJECT}%22%2C%22actions.service.name%22%3A%22${SERVICE_NAME}%22%2C%22actions.package.version%22%3A%22${PROJECT_VERSION}%22%7D&offset=0&limit=1" \ + -H 'accept: application/json' \ + -H 'Authorization: Bearer '"${BROKER_JWT}"'' \ + -d '') + if echo "$RESPONSE" | jq -e '.statusCode == 401' > /dev/null; then + echo "Status code is 401. This indicates an authorization error." + echo "Please check if your Broker Token is valid. Teams can generate a new one in Broker if needed." + echo "Link: https://broker.io.nrs.gov.bc.ca/browse/brokerAccount" + echo "Exiting..." + exit 1 + fi + echo "project_version=${PROJECT_VERSION}" >> $GITHUB_OUTPUT + echo "build_guid=$(echo ${RESPONSE} | jq -r '.data[].id')" >> $GITHUB_OUTPUT + echo "build_number=$(echo ${RESPONSE} | jq -r '.data[].actions[].package.buildNumber')" >> $GITHUB_OUTPUT + echo "artifact_name=$(echo ${RESPONSE} | jq -r '.data[].actions[].artifacts[].name')" >> $GITHUB_OUTPUT + artifact_checksum=$(echo ${RESPONSE} | jq -r '.data[].actions[].artifacts[].checksum') + echo "artifact_sha256=${artifact_checksum#sha256:}" >> $GITHUB_OUTPUT + env: + BROKER_URL: https://broker.io.nrs.gov.bc.ca + BROKER_JWT: ${{ secrets.<%= brokerJwt %> }} + SERVICE_PROJECT: ${{ env.SERVICE_PROJECT }} + SERVICE_NAME: ${{ env.SERVICE_NAME }} + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + ref: ${{ github.ref }} + - name: Set up Java + uses: actions/setup-java@v4 + with: + java-version: '8' + distribution: 'temurin' + cache: maven + - name: Set download URL + id: set-download-url + run: | + sudo apt-get -qq install libxml2-utils + GROUP_ID=$(mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout --file <%= pomRoot %>pom.xml) + GROUP_ID_PATH="${GROUP_ID//.//}" + PACKAGE_TYPE=$(mvn help:evaluate -Dexpression=project.packaging -q -DforceStdout --file <%= pomRoot %>pom.xml) + ARTIFACT_NAME="${SERVICE_NAME}-${PROJECT_VERSION}.${PACKAGE_TYPE}" + DOWNLOAD_URL="${PACKAGE_REPO}/${GROUP_ID_PATH}/${SERVICE_NAME}/${PROJECT_VERSION}/${ARTIFACT_NAME}" + echo "${DOWNLOAD_URL}" + echo "download_url=$(echo ${DOWNLOAD_URL})" >> $GITHUB_OUTPUT + env: + SERVICE_NAME: ${{ env.SERVICE_NAME }} + PROJECT_VERSION: ${{ steps.set-tag-output.outputs.project_version }} + PACKAGE_REPO: ${{ env.PACKAGE_REPO }} + submit-job: + name: Submit job + if: | + always() && + ((needs.deploy-build.result == 'success' && needs.deploy-tag.result == 'skipped') || + (needs.deploy-build.result == 'skipped' && needs.deploy-tag.result == 'success')) + needs: [deploy-build, deploy-tag] + runs-on: ubuntu-latest + steps: + - name: Submit a job to Jenkins +<% if (gitHubPackages) { -%> + run: | + curl \ + --data-urlencode "token=${{ secrets.JENKINS_TOKEN }}" \ + --data-urlencode "githubToken=${{ secrets.GITHUB_TOKEN }}" \ + --data-urlencode "artifactSha256=${ARTIFACT_SHA256}" \ + --data-urlencode "projectVersion=${PROJECT_VERSION}" \ + --data-urlencode "gitBranch=${{ github.ref_name }}" \ + --data-urlencode "intentionId=${BUILD_GUID}" \ + --data-urlencode "gitTag=${{ (startsWith(github.ref, 'refs/tags/') && github.ref_name) || '' }}" \ + --data-urlencode "configBranch=${{ inputs.config_branch || '' }}" \ + --data-urlencode "downloadUrl=${DOWNLOAD_URL}" \ + --data-urlencode "downloadType=GITHUB" \ + -H "Connection: close" \ + ${{ env.URL }}/${{ env.JOB }} +<% } else { -%> + run: | + curl \ + --data-urlencode "token=${{ secrets.JENKINS_TOKEN }}" \ + --data-urlencode "githubToken=${{ secrets.GITHUB_TOKEN }}" \ + --data-urlencode "artifactSha256=${ARTIFACT_SHA256}" \ + --data-urlencode "projectVersion=${PROJECT_VERSION}" \ + --data-urlencode "gitBranch=${{ github.ref_name }}" \ + --data-urlencode "intentionId=${BUILD_GUID}" \ + --data-urlencode "gitTag=${{ (startsWith(github.ref, 'refs/tags/') && github.ref_name) || '' }}" \ + --data-urlencode "configBranch=${{ inputs.config_branch || '' }}" \ + --data-urlencode "downloadUrl=${DOWNLOAD_URL}" \ + --data-urlencode "downloadType=ARTIFACTORY" \ + -H "Connection: close" \ + ${{ env.URL }}/${{ env.JOB }} +<% } -%> + env: + PROJECT_VERSION: ${{ needs.deploy-build.outputs.project_version || needs.deploy-tag.outputs.project_version }} + BUILD_GUID: ${{ needs.deploy-build.outputs.build_guid || needs.deploy-tag.outputs.build_guid }} + BUILD_NUMBER: ${{ needs.deploy-build.outputs.build_number || needs.deploy-tag.outputs.build_number }} + ARTIFACT_SHA256: ${{ needs.deploy-build.outputs.artifact_sha256 || needs.deploy-tag.outputs.artifact_sha256 }} + DOWNLOAD_URL: ${{ needs.deploy-build.outputs.download_url || needs.deploy-tag.outputs.download_url }} + # The automatically generated GitHub token will expire when the workflow ends. We need to wait so the job has time to clone the repo + # and download the package + - name: Sleep + run: sleep 90s + shell: bash diff --git a/generators/gh-nodejs-build/templates/deployment-intention.json b/generators/gh-nodejs-build/templates/deployment-intention.json new file mode 100644 index 0000000..099b303 --- /dev/null +++ b/generators/gh-nodejs-build/templates/deployment-intention.json @@ -0,0 +1,59 @@ +{ + "event": { + "provider": "EVENT_PROVIDER", + "reason": "Job triggered", + "url": "JOB_URL" + }, + "actions": [ + { + "action": "server-access", + "id": "login", + "provision": ["token/self"], + "service": { + "name": "<%= serviceName %>", + "project": "<%= projectName %>", + "environment": "", + "target": { + "name": "jenkins-apps", + "project": "jenkins", + "environment": "production" + } + } + }, + { + "action": "package-configure", + "id": "configure", + "provision": ["token/self"], + "service": { + "name": "<%= serviceName %>", + "project": "<%= projectName %>", + "environment": "" + } + }, + { + "action": "package-installation", + "id": "install", + "provision": [], + "cloud": { + "target": { + "provider": "dxcas" + } + }, + "service": { + "name": "<%= serviceName %>", + "project": "<%= projectName %>", + "environment": "" + }, + "package": { + "version": "", + "buildGuid": "" + }, + "source": { + "action": "package-build#build" + } + } + ], + "user": { + "name": "USER_ID" + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d3cf3eb..5c5db21 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,19 +9,19 @@ "version": "1.0.0", "license": "Apache-2.0", "dependencies": { - "yaml": "^2.5.1", - "yeoman-generator": "^7.3.2", + "yaml": "^2.6.1", + "yeoman-generator": "^7.4.0", "yosay": "^3.0.0" }, "devDependencies": { - "eslint": "^9.11.1", + "eslint": "^9.17.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", "jest": "^29.7.0", - "lint-staged": "^15.2.10", - "prettier": "^3.3.3", + "lint-staged": "^15.3.0", + "prettier": "^3.4.2", "yeoman-assert": "^3.1.1", - "yeoman-test": "^10.0.0" + "yeoman-test": "^10.0.1" }, "engines": { "npm": ">= 4.0.0" @@ -627,9 +627,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.16.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.16.0.tgz", - "integrity": "sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==", + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz", + "integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==", "dev": true, "license": "MIT", "engines": { @@ -1654,67 +1654,80 @@ } }, "node_modules/@octokit/auth-token": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", - "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", + "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==", "license": "MIT", - "dependencies": { - "@octokit/types": "^6.0.3" + "engines": { + "node": ">= 14" } }, "node_modules/@octokit/core": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", - "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", + "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", "license": "MIT", "dependencies": { - "@octokit/auth-token": "^2.4.4", - "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.6.3", - "@octokit/request-error": "^2.0.5", - "@octokit/types": "^6.0.3", + "@octokit/auth-token": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", "before-after-hook": "^2.2.0", "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" } }, "node_modules/@octokit/endpoint": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", - "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz", + "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==", "license": "MIT", "dependencies": { - "@octokit/types": "^6.0.3", + "@octokit/types": "^9.0.0", "is-plain-object": "^5.0.0", "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" } }, "node_modules/@octokit/graphql": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", - "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", + "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", "license": "MIT", "dependencies": { - "@octokit/request": "^5.6.0", - "@octokit/types": "^6.0.3", + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" } }, "node_modules/@octokit/openapi-types": { - "version": "12.11.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", - "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==", + "version": "18.1.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz", + "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==", "license": "MIT" }, "node_modules/@octokit/plugin-paginate-rest": { - "version": "2.21.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz", - "integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", + "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", "license": "MIT", "dependencies": { - "@octokit/types": "^6.40.0" + "@octokit/tsconfig": "^1.0.2", + "@octokit/types": "^9.2.3" + }, + "engines": { + "node": ">= 14" }, "peerDependencies": { - "@octokit/core": ">=2" + "@octokit/core": ">=4" } }, "node_modules/@octokit/plugin-request-log": { @@ -1727,62 +1740,88 @@ } }, "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "5.16.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz", - "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz", + "integrity": "sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA==", "license": "MIT", "dependencies": { - "@octokit/types": "^6.39.0", - "deprecation": "^2.3.1" + "@octokit/types": "^10.0.0" + }, + "engines": { + "node": ">= 14" }, "peerDependencies": { "@octokit/core": ">=3" } }, + "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz", + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^18.0.0" + } + }, "node_modules/@octokit/request": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", - "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz", + "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==", "license": "MIT", "dependencies": { - "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.1.0", - "@octokit/types": "^6.16.1", + "@octokit/endpoint": "^7.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", "is-plain-object": "^5.0.0", "node-fetch": "^2.6.7", "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" } }, "node_modules/@octokit/request-error": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", - "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", + "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", "license": "MIT", "dependencies": { - "@octokit/types": "^6.0.3", + "@octokit/types": "^9.0.0", "deprecation": "^2.0.0", "once": "^1.4.0" + }, + "engines": { + "node": ">= 14" } }, "node_modules/@octokit/rest": { - "version": "18.12.0", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz", - "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==", + "version": "19.0.13", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.13.tgz", + "integrity": "sha512-/EzVox5V9gYGdbAI+ovYj3nXQT1TtTHRT+0eZPcuC05UFSWO3mdO9UY1C0i2eLF9Un1ONJkAk+IEtYGAC+TahA==", "license": "MIT", "dependencies": { - "@octokit/core": "^3.5.1", - "@octokit/plugin-paginate-rest": "^2.16.8", + "@octokit/core": "^4.2.1", + "@octokit/plugin-paginate-rest": "^6.1.2", "@octokit/plugin-request-log": "^1.0.4", - "@octokit/plugin-rest-endpoint-methods": "^5.12.0" + "@octokit/plugin-rest-endpoint-methods": "^7.1.2" + }, + "engines": { + "node": ">= 14" } }, + "node_modules/@octokit/tsconfig": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", + "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==", + "license": "MIT" + }, "node_modules/@octokit/types": { - "version": "6.41.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", - "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", + "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==", "license": "MIT", "dependencies": { - "@octokit/openapi-types": "^12.11.0" + "@octokit/openapi-types": "^18.0.0" } }, "node_modules/@pkgr/core": { @@ -1846,18 +1885,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, "node_modules/@sindresorhus/merge-streams": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", @@ -1890,18 +1917,6 @@ "@sinonjs/commons": "^3.0.0" } }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "license": "MIT", - "dependencies": { - "defer-to-connect": "^2.0.1" - }, - "engines": { - "node": ">=14.16" - } - }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -1977,12 +1992,6 @@ "@types/node": "*" } }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", - "license": "MIT" - }, "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", @@ -2525,33 +2534,6 @@ "dev": true, "license": "MIT" }, - "node_modules/cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", - "license": "MIT", - "engines": { - "node": ">=14.16" - } - }, - "node_modules/cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", - "license": "MIT", - "dependencies": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2594,9 +2576,9 @@ "license": "CC-BY-4.0" }, "node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -2960,9 +2942,9 @@ } }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2976,33 +2958,6 @@ } } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/dedent": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", @@ -3044,15 +2999,6 @@ "node": ">=0.10.0" } }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/deprecation": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", @@ -3188,9 +3134,9 @@ } }, "node_modules/eslint": { - "version": "9.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.16.0.tgz", - "integrity": "sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==", + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.17.0.tgz", + "integrity": "sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==", "dev": true, "license": "MIT", "dependencies": { @@ -3199,7 +3145,7 @@ "@eslint/config-array": "^0.19.0", "@eslint/core": "^0.9.0", "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.16.0", + "@eslint/js": "9.17.0", "@eslint/plugin-kit": "^0.2.3", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -3208,7 +3154,7 @@ "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.5", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.2.0", @@ -3709,15 +3655,6 @@ "dev": true, "license": "ISC" }, - "node_modules/form-data-encoder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", - "license": "MIT", - "engines": { - "node": ">= 14.17" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3796,6 +3733,7 @@ "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" @@ -3805,15 +3743,15 @@ } }, "node_modules/github-username": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/github-username/-/github-username-7.0.0.tgz", - "integrity": "sha512-mzCjmmR1LcNf0/qvkJRO63di2lUUuEoRuCqzflq8wrpAajOo7zLSXOTTuj2qr1DhFY2pruw5JLw/CokZU/3ilg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/github-username/-/github-username-8.0.0.tgz", + "integrity": "sha512-zq6QMHQKeGfhvdLMyT/nskL8ClE3Y9DFDRv3CgpBAIR1lGiL9GFZcgpmF0nMzegfMMLG3TmsEgHoFf8DcD25Lw==", "license": "MIT", "dependencies": { - "@octokit/rest": "^18.12.0" + "@octokit/rest": "^19.0.13" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -3899,31 +3837,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -3978,25 +3891,6 @@ "dev": true, "license": "MIT" }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "license": "BSD-2-Clause" - }, - "node_modules/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "license": "MIT", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -5523,6 +5417,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, "license": "MIT" }, "node_modules/json-parse-even-better-errors": { @@ -5569,6 +5464,7 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, "license": "MIT", "dependencies": { "json-buffer": "3.0.1" @@ -5584,16 +5480,28 @@ "node": ">=6" } }, + "node_modules/ky": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/ky/-/ky-1.7.4.tgz", + "integrity": "sha512-zYEr/gh7uLW2l4su11bmQ2M9xLgQLjyvx58UyNM/6nuqyWFHPX5ktMjvpev3F8QWdjSsHUpnWew4PBCswBNuMQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } + }, "node_modules/latest-version": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", - "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-9.0.0.tgz", + "integrity": "sha512-7W0vV3rqv5tokqkBAFV1LbR7HPOWzXQDpDgEuib/aJ1jsZZx6x3c2mBI+TJhJzOhkGeaLbCKEHXEXLfirtG2JA==", "license": "MIT", "dependencies": { - "package-json": "^8.1.0" + "package-json": "^10.0.0" }, "engines": { - "node": ">=14.16" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5624,9 +5532,9 @@ } }, "node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "dev": true, "license": "MIT", "engines": { @@ -5644,22 +5552,22 @@ "license": "MIT" }, "node_modules/lint-staged": { - "version": "15.2.10", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.10.tgz", - "integrity": "sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg==", + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.3.0.tgz", + "integrity": "sha512-vHFahytLoF2enJklgtOtCtIjZrKD/LoxlaUusd5nh7dWv/dkKQJY74ndFSzxCdv7g0ueGg1ORgTSt4Y9LPZn9A==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "~5.3.0", + "chalk": "~5.4.1", "commander": "~12.1.0", - "debug": "~4.3.6", + "debug": "~4.4.0", "execa": "~8.0.1", - "lilconfig": "~3.1.2", - "listr2": "~8.2.4", + "lilconfig": "~3.1.3", + "listr2": "~8.2.5", "micromatch": "~4.0.8", "pidtree": "~0.6.0", "string-argv": "~0.3.2", - "yaml": "~2.5.0" + "yaml": "~2.6.1" }, "bin": { "lint-staged": "bin/lint-staged.js" @@ -5802,19 +5710,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", - "dev": true, - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/listr2": { "version": "8.2.5", "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", @@ -6068,18 +5963,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -6261,18 +6144,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -6427,18 +6298,6 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-url": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", - "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -6588,15 +6447,6 @@ "node": ">=0.10.0" } }, - "node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "license": "MIT", - "engines": { - "node": ">=12.20" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -6670,18 +6520,18 @@ } }, "node_modules/package-json": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", - "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-10.0.1.tgz", + "integrity": "sha512-ua1L4OgXSBdsu1FPb7F3tYH0F48a6kxvod4pLUlGY9COeJAJQNX/sNH2IiEmsxw7lqYiAwrdHMjz1FctOsyDQg==", "license": "MIT", "dependencies": { - "got": "^12.1.0", - "registry-auth-token": "^5.0.1", - "registry-url": "^6.0.0", - "semver": "^7.3.7" + "ky": "^1.2.0", + "registry-auth-token": "^5.0.2", + "registry-url": "^6.0.1", + "semver": "^7.6.0" }, "engines": { - "node": ">=14.16" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6905,9 +6755,9 @@ } }, "node_modules/prettier": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.1.tgz", - "integrity": "sha512-G+YdqtITVZmOJje6QkXQWzl3fSfMxFwm1tjTyo9exhkmWSqC4Yhd1+lug++IlR2mvRVAxEDDWYkQdeSztajqgg==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", "dev": true, "license": "MIT", "bin": { @@ -7021,18 +6871,6 @@ "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", "license": "MIT" }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -7211,12 +7049,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "license": "MIT" - }, "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", @@ -7260,21 +7092,6 @@ "node": ">=10" } }, - "node_modules/responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "license": "MIT", - "dependencies": { - "lowercase-keys": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/restore-cursor": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", @@ -8310,9 +8127,9 @@ } }, "node_modules/yeoman-generator": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-7.3.3.tgz", - "integrity": "sha512-wIWCSRvm0R+Y10B+KJ7wEDo/WPyDMC2CG/2lxR/JnWkl40mtmiM442P5jlklMwp/1m7QCWhfnU8FHvlAfbGXhw==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-7.4.0.tgz", + "integrity": "sha512-9vkum9nQQ9bU37kH55SymKFsE/ndkUtyz8T+xTaWMOKhNCj5BbqLSrzy7cJbNQivs/7YlXuUU5HL58kQB2/9gA==", "license": "BSD-2-Clause", "dependencies": { "@types/lodash-es": "^4.17.9", @@ -8321,9 +8138,9 @@ "chalk": "^5.3.0", "debug": "^4.1.1", "execa": "^8.0.1", - "github-username": "^7.0.0", + "github-username": "^8.0.0", "json-schema": "^0.4.0", - "latest-version": "^7.0.0", + "latest-version": "^9.0.0", "lodash-es": "^4.17.21", "mem-fs-editor": "^11.0.1", "minimist": "^1.2.8", diff --git a/package.json b/package.json index 485e59a..a13093f 100644 --- a/package.json +++ b/package.json @@ -17,19 +17,19 @@ "test": "jest" }, "dependencies": { - "yaml": "^2.5.1", - "yeoman-generator": "^7.3.2", + "yaml": "^2.6.1", + "yeoman-generator": "^7.4.0", "yosay": "^3.0.0" }, "devDependencies": { - "eslint": "^9.11.1", + "eslint": "^9.17.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", "jest": "^29.7.0", - "lint-staged": "^15.2.10", - "prettier": "^3.3.3", + "lint-staged": "^15.3.0", + "prettier": "^3.4.2", "yeoman-assert": "^3.1.1", - "yeoman-test": "^10.0.0" + "yeoman-test": "^10.0.1" }, "type": "module", "license": "Apache-2.0" From c7bb4fcc71691141addfd9e5a118a86db047e4cd Mon Sep 17 00:00:00 2001 From: Matthew Bystedt Date: Tue, 31 Dec 2024 16:27:27 -0800 Subject: [PATCH 2/3] fix: build setup --- .../templates/build-release.yaml | 11 +++- .../templates/build-intention.json | 2 +- .../templates/build-release.yaml | 52 +++++++++++++------ 3 files changed, 45 insertions(+), 20 deletions(-) diff --git a/generators/gh-maven-build/templates/build-release.yaml b/generators/gh-maven-build/templates/build-release.yaml index 00b4fb6..2e501fe 100644 --- a/generators/gh-maven-build/templates/build-release.yaml +++ b/generators/gh-maven-build/templates/build-release.yaml @@ -102,7 +102,7 @@ jobs: broker_jwt: ${{ secrets.<%= brokerJwt %> }} intention_path: intention.json quickstart: true - - name: Set intention ID for deployment job + - name: Echo intention ID for deploy job id: set-intention-id run: | echo "intention_id=${INTENTION_ID}" >> $GITHUB_OUTPUT @@ -163,6 +163,13 @@ jobs: BUILD_TOKEN: ${{ env.ACTION_TOKEN_BUILD }} <% } -%> - name: Close intention - uses: bcgov-nr/action-broker-intention-close@v1 + if: ${{ success() && env.INTENTION_TOKEN != '' }} + uses: bcgov-nr/action-broker-intention-close@v3 with: intention_token: ${{ env.INTENTION_TOKEN }} + - name: Close intention (Failure) + if: ${{ failure() && env.INTENTION_TOKEN != '' }} + uses: bcgov-nr/action-broker-intention-close@v3 + with: + intention_token: ${{ env.INTENTION_TOKEN }} + outcome: failure diff --git a/generators/gh-nodejs-build/templates/build-intention.json b/generators/gh-nodejs-build/templates/build-intention.json index 72fd495..0b17b40 100644 --- a/generators/gh-nodejs-build/templates/build-intention.json +++ b/generators/gh-nodejs-build/templates/build-intention.json @@ -19,7 +19,7 @@ "buildVersion": "", "buildNumber": 0, "name": "<%= serviceName %>", - "type": "application/vnd.oci.image.layer.v1.tar" + "type": "application/vnd.oci.image.layer.v1.tar+gzip" } } ], diff --git a/generators/gh-nodejs-build/templates/build-release.yaml b/generators/gh-nodejs-build/templates/build-release.yaml index 79659c5..f0f1082 100644 --- a/generators/gh-nodejs-build/templates/build-release.yaml +++ b/generators/gh-nodejs-build/templates/build-release.yaml @@ -42,9 +42,9 @@ jobs: contents: read packages: write outputs: - project_version: ${{ steps.set-build-output-parameters.outputs.project_version }} + project_version: ${{ steps.set-version.outputs.project_version }} intention_id: ${{ steps.set-intention-id.outputs.intention_id }} - branch: $${{ steps.set-branch.outputs.branch }} + branch: $${{ steps.set-version.outputs.branch }} steps: - name: Checkout repository uses: actions/checkout@v4 @@ -59,20 +59,28 @@ jobs: with: node-version: 22 cache: 'npm' - - name: Set branch - id: set-branch - if: ${{ ! startsWith(github.ref, 'refs/tags/v') }} + - name: Set version + id: set-version run: | if [[ ${{ startsWith(github.ref, 'refs/heads/') }} = true ]]; then - echo "branch=${{ github.ref_name }}" >> "$GITHUB_OUTPUT" + version=$(cat package.json | jq -r '.version') + echo "project_version=$version-${{ github.ref_name }}" >> "$GITHUB_OUTPUT" + echo "tag=${{ github.ref_name }}" >> "$GITHUB_OUTPUT" fi if [[ ${{ startsWith(github.ref, 'refs/pull/') }} = true ]]; then - echo "branch=${{ github.head_ref }}" >> "$GITHUB_OUTPUT" + version=$(cat package.json | jq -r '.version') + echo "project_version=$version-${{ github.ref_name }}" >> "$GITHUB_OUTPUT" + echo "tag=${{ github.ref_name }}" >> "$GITHUB_OUTPUT" + fi + if [[ ${{ startsWith(github.ref, 'refs/tags/v') }} = true ]]; then + echo "tag=${{ github.ref_name }}" >> "$GITHUB_OUTPUT" + TAG=${{ github.ref_name }} + version="${TAG#v}" + echo "project_version=$version" >> $GITHUB_OUTPUT fi - name: Set build output parameters id: set-build-output-parameters run: | - echo "project_version=1.0.0" >> $GITHUB_OUTPUT echo "git_commit=$(git rev-parse --verify HEAD)" >> $GITHUB_OUTPUT echo "build_guid=uuid::$(uuidgen)" >> $GITHUB_OUTPUT - name: Build intention @@ -84,14 +92,14 @@ jobs: PACKAGE_BUILD_GUID: ${{ steps.set-build-output-parameters.outputs.build_guid }} PACKAGE_BUILD_NUMBER: ${{ github.run_number }} PACKAGE_BUILD_VERSION: ${{ steps.set-build-output-parameters.outputs.git_commit }} - PACKAGE_VERSION: ${{ steps.set-build-output-parameters.outputs.project_version }} + PACKAGE_VERSION: ${{ steps.set-version.outputs.project_version }} - name: Open intention uses: bcgov-nr/action-broker-intention-open@v2 with: broker_jwt: ${{ secrets.<%= brokerJwt %> }} intention_path: intention.json quickstart: true - - name: Set intention ID for deployment job + - name: Echo intention ID for deploy job id: set-intention-id run: | echo "intention_id=${INTENTION_ID}" >> $GITHUB_OUTPUT @@ -102,23 +110,33 @@ jobs: - name: Build artifact run: npm run build --if-present - name: Push build + id: publish-artifact run: | - oras push ghcr.io/${{ github.repository_owner }}/${{ github.repository}}:${PROJECT_VERSION} dist - MANIFEST=$(oras manifest fetch ghcr.io/${{ github.repository_owner }}/${{ github.repository}}:${PROJECT_VERSION}) - echo "artifact_sha256=$(echo $MANIFEST | jq -r '.layers[0].digest')" >> $GITHUB_OUTPUT + oras login ghcr.io -u ${{ github.actor }} --password-stdin <<< ${{ secrets.GITHUB_TOKEN }} + oras push ghcr.io/${{ github.repository }}/package:${PROJECT_TAG} dist + MANIFEST=$(oras manifest fetch ghcr.io/${{ github.repository}}/package:${PROJECT_TAG}) + echo "artifact_sha256=$(echo $MANIFEST | jq -r '.layers[1].digest')" >> $GITHUB_OUTPUT + echo "artifact_size=$(echo $MANIFEST | jq -r '.layers[1].size')" >> $GITHUB_OUTPUT env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PROJECT_VERSION: ${{ steps.set-build-output-parameters.outputs.project_version }} + PROJECT_TAG: ${{ steps.set-version.outputs.tag }} - name: Send build info run: | curl -s POST ${{ env.BROKER_URL }}/v1/intention/action/patch \ -H 'Content-Type: application/json' \ -H 'X-Broker-Token: '"${BUILD_TOKEN}"'' \ - -d '{"package":{"checksum": "sha256:'${ARTIFACT_SHA256}'"}}' + -d '{"package":{"checksum": "sha256:'${ARTIFACT_SHA256}'", "size": '${ARTIFACT_SIZE}'}}' env: ARTIFACT_SHA256: ${{ steps.publish-artifact.outputs.artifact_sha256 }} + ARTIFACT_SIZE: ${{ steps.publish-artifact.outputs.artifact_size }} BUILD_TOKEN: ${{ env.ACTION_TOKEN_BUILD }} - name: Close intention - uses: bcgov-nr/action-broker-intention-close@v1 + if: ${{ success() && env.INTENTION_TOKEN != '' }} + uses: bcgov-nr/action-broker-intention-close@v3 + with: + intention_token: ${{ env.INTENTION_TOKEN }} + - name: Close intention (Failure) + if: ${{ failure() && env.INTENTION_TOKEN != '' }} + uses: bcgov-nr/action-broker-intention-close@v3 with: intention_token: ${{ env.INTENTION_TOKEN }} + outcome: failure From 5a630a134429eb50e150dd955501d5bdbfa4d978 Mon Sep 17 00:00:00 2001 From: Matthew Bystedt Date: Thu, 2 Jan 2025 09:26:16 -0800 Subject: [PATCH 3/3] feat: working build-release --- .../templates/build-release.yaml | 9 +- .../gh-nodejs-build/templates/deploy.yaml | 234 ------------------ .../templates/deployment-intention.json | 59 ----- 3 files changed, 5 insertions(+), 297 deletions(-) delete mode 100644 generators/gh-nodejs-build/templates/deploy.yaml delete mode 100644 generators/gh-nodejs-build/templates/deployment-intention.json diff --git a/generators/gh-nodejs-build/templates/build-release.yaml b/generators/gh-nodejs-build/templates/build-release.yaml index f0f1082..803d08f 100644 --- a/generators/gh-nodejs-build/templates/build-release.yaml +++ b/generators/gh-nodejs-build/templates/build-release.yaml @@ -113,10 +113,11 @@ jobs: id: publish-artifact run: | oras login ghcr.io -u ${{ github.actor }} --password-stdin <<< ${{ secrets.GITHUB_TOKEN }} - oras push ghcr.io/${{ github.repository }}/package:${PROJECT_TAG} dist - MANIFEST=$(oras manifest fetch ghcr.io/${{ github.repository}}/package:${PROJECT_TAG}) - echo "artifact_sha256=$(echo $MANIFEST | jq -r '.layers[1].digest')" >> $GITHUB_OUTPUT - echo "artifact_size=$(echo $MANIFEST | jq -r '.layers[1].size')" >> $GITHUB_OUTPUT + oras push --export-manifest manifest.json ghcr.io/${{ github.repository }}/package:${PROJECT_TAG} dist node_modules package.json package-lock.json + MANIFEST=$(cat ./manifest.json) + echo $MANIFEST + echo "artifact_sha256=$(echo $MANIFEST | jq -r '.layers[] | select(.annotations["org.opencontainers.image.title"] == "dist") | .digest')" >> $GITHUB_OUTPUT + echo "artifact_size=$(echo $MANIFEST | jq -r '.layers | map(.size) | add')" >> $GITHUB_OUTPUT env: PROJECT_TAG: ${{ steps.set-version.outputs.tag }} - name: Send build info diff --git a/generators/gh-nodejs-build/templates/deploy.yaml b/generators/gh-nodejs-build/templates/deploy.yaml deleted file mode 100644 index 49abdfc..0000000 --- a/generators/gh-nodejs-build/templates/deploy.yaml +++ /dev/null @@ -1,234 +0,0 @@ -name: Deploy - -on: - workflow_dispatch: - inputs: - config_branch: - description: 'Use branch for testing configuration changes' - required: false - type: string - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -env: - SERVICE_PROJECT: <%= projectName %> - SERVICE_NAME: <%= serviceName %> - JOB: buildByToken/buildWithParameters?job=<%= projectName %>/<%= serviceName %> - URL: https://cd.io.nrs.gov.bc.ca -<% if (gitHubPackages) { -%> - PACKAGE_REPO: https://maven.pkg.github.com/<%= gitHubOwnerPack %> -<% } else { -%> - PACKAGE_REPO: https://artifacts.developer.gov.bc.ca/artifactory/<%= artifactoryProject %>-<%= projectName %>-<%= artifactoryPackageType %>-local -<% } -%> - -jobs: - check_token_expiration: - uses: ./.github/workflows/check-token.yaml - secrets: - token: ${{ secrets.<%= brokerJwt %> }} - deploy-build: - name: Deploy development version - if: ${{ ! startsWith(github.ref, 'refs/tags/') }} - runs-on: ubuntu-latest - needs: check_token_expiration - outputs: - project_version: ${{ steps.set-build-output.outputs.project_version }} - build_guid: ${{ steps.set-build-output.outputs.build_guid }} - build_number: ${{ steps.set-build-output.outputs.build_number }} - artifact_name: ${{ steps.set-build-output.outputs.artifact_name }} - artifact_sha256: ${{ steps.set-build-output.outputs.artifact_sha256 }} - download_url: ${{ steps.set-download-url.outputs.download_url }} - steps: - - name: Set build output - id: set-build-output - run: | - RESPONSE=$(curl -s -X 'POST' \ - "${BROKER_URL}/v1/intention/search?where=%7B%22actions.action%22%3A%22package-build%22%2C%22actions.service.project%22%3A%22${SERVICE_PROJECT}%22%2C%22actions.service.name%22%3A%22${SERVICE_NAME}%22%2C%22actions.package.buildVersion%22%3A%22${GITHUB_SHA}%22%7D&offset=0&limit=1" \ - -H 'accept: application/json' \ - -H 'Authorization: Bearer '"${BROKER_JWT}"'' \ - -d '') - if echo "$RESPONSE" | jq -e '.statusCode == 401' > /dev/null; then - echo "Status code is 401. This indicates an authorization error." - echo "Please check if your Broker Token is valid. Teams can generate a new one in Broker if needed." - echo "Link: https://broker.io.nrs.gov.bc.ca/browse/brokerAccount" - echo "Exiting..." - exit 1 - fi - echo "project_version=$(echo ${RESPONSE} | jq -r '.data[].actions[].package.version')" >> $GITHUB_OUTPUT - echo "build_guid=$(echo ${RESPONSE} | jq -r '.data[].id')" >> $GITHUB_OUTPUT - echo "build_number=$(echo ${RESPONSE} | jq -r '.data[].actions[].package.buildNumber')" >> $GITHUB_OUTPUT - echo "artifact_name=$(echo ${RESPONSE} | jq -r '.data[].actions[].artifacts[].name')" >> $GITHUB_OUTPUT - artifact_checksum=$(echo ${RESPONSE} | jq -r '.data[].actions[].artifacts[].checksum') - echo "artifact_sha256=${artifact_checksum#sha256:}" >> $GITHUB_OUTPUT - env: - BROKER_URL: https://broker.io.nrs.gov.bc.ca - BROKER_JWT: ${{ secrets.<%= brokerJwt %> }} - SERVICE_PROJECT: ${{ env.SERVICE_PROJECT }} - SERVICE_NAME: ${{ env.SERVICE_NAME }} - GITHUB_SHA: ${{ github.sha }} - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - fetch-tags: true - ref: ${{ github.ref }} - - name: Set up Java - uses: actions/setup-java@v4 - with: - java-version: '8' - distribution: 'temurin' - cache: maven - - name: Set download URL - id: set-download-url -<% if (gitHubPackages) { -%> - run: | - sudo apt-get -qq install libxml2-utils - GROUP_ID=$(mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout --file <%= pomRoot %>pom.xml) - GROUP_ID_PATH="${GROUP_ID//.//}" - PACKAGE_TYPE=$(mvn help:evaluate -Dexpression=project.packaging -q -DforceStdout --file <%= pomRoot %>pom.xml) - curl -LO "${PACKAGE_REPO}/${GROUP_ID_PATH}/${SERVICE_NAME}/${PROJECT_VERSION}/maven-metadata.xml" -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" - TIMESTAMP=$(xmllint --xpath '//metadata/versioning/snapshot/timestamp/text()' maven-metadata.xml) - BUILD_NUMBER=$(xmllint --xpath '//metadata/versioning/snapshot/buildNumber/text()' maven-metadata.xml) - SNAPSHOT_VERSION="${PROJECT_VERSION//SNAPSHOT/$TIMESTAMP-$BUILD_NUMBER}" - ARTIFACT_NAME="${SERVICE_NAME}-${SNAPSHOT_VERSION}.${PACKAGE_TYPE}" - DOWNLOAD_URL="${PACKAGE_REPO}/${GROUP_ID_PATH}/${SERVICE_NAME}/${PROJECT_VERSION}/${ARTIFACT_NAME}" - echo "${DOWNLOAD_URL}" - echo "download_url=$(echo ${DOWNLOAD_URL})" >> $GITHUB_OUTPUT -<% } else { -%> - run: | - sudo apt-get -qq install libxml2-utils - GROUP_ID=$(mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout --file <%= pomRoot %>pom.xml) - GROUP_ID_PATH="${GROUP_ID//.//}" - PACKAGE_TYPE=$(mvn help:evaluate -Dexpression=project.packaging -q -DforceStdout --file <%= pomRoot %>pom.xml) - SNAPSHOT_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout --file <%= pomRoot %>pom.xml) - ARTIFACT_NAME="${SERVICE_NAME}-${SNAPSHOT_VERSION}.${PACKAGE_TYPE}" - DOWNLOAD_URL="${PACKAGE_REPO}/${GROUP_ID_PATH}/${SERVICE_NAME}/${PROJECT_VERSION}/${ARTIFACT_NAME}" - echo "${DOWNLOAD_URL}" - echo "download_url=$(echo ${DOWNLOAD_URL})" >> $GITHUB_OUTPUT -<% } -%> - env: - SERVICE_NAME: ${{ env.SERVICE_NAME }} - PROJECT_VERSION: ${{ steps.set-build-output.outputs.project_version }} - PACKAGE_REPO: ${{ env.PACKAGE_REPO }} - deploy-tag: - name: Deploy release version - if: ${{ startsWith(github.ref, 'refs/tags/') }} - runs-on: ubuntu-latest - needs: check_token_expiration - outputs: - project_version: ${{ steps.set-tag-output.outputs.project_version }} - build_guid: ${{ steps.set-tag-output.outputs.build_guid }} - build_number: ${{ steps.set-tag-output.outputs.build_number }} - artifact_name: ${{ steps.set-tag-output.outputs.artifact_name }} - artifact_sha256: ${{ steps.set-tag-output.outputs.artifact_sha256 }} - download_url: ${{ steps.set-download-url.outputs.download_url }} - steps: - - name: Set tag output - id: set-tag-output - run: | - TAG=${{ github.ref_name }} - PROJECT_VERSION=${TAG#v} - RESPONSE=$(curl -s -X 'POST' \ - "${BROKER_URL}/v1/intention/search?where=%7B%22actions.action%22%3A%22package-build%22%2C%22actions.service.project%22%3A%22${SERVICE_PROJECT}%22%2C%22actions.service.name%22%3A%22${SERVICE_NAME}%22%2C%22actions.package.version%22%3A%22${PROJECT_VERSION}%22%7D&offset=0&limit=1" \ - -H 'accept: application/json' \ - -H 'Authorization: Bearer '"${BROKER_JWT}"'' \ - -d '') - if echo "$RESPONSE" | jq -e '.statusCode == 401' > /dev/null; then - echo "Status code is 401. This indicates an authorization error." - echo "Please check if your Broker Token is valid. Teams can generate a new one in Broker if needed." - echo "Link: https://broker.io.nrs.gov.bc.ca/browse/brokerAccount" - echo "Exiting..." - exit 1 - fi - echo "project_version=${PROJECT_VERSION}" >> $GITHUB_OUTPUT - echo "build_guid=$(echo ${RESPONSE} | jq -r '.data[].id')" >> $GITHUB_OUTPUT - echo "build_number=$(echo ${RESPONSE} | jq -r '.data[].actions[].package.buildNumber')" >> $GITHUB_OUTPUT - echo "artifact_name=$(echo ${RESPONSE} | jq -r '.data[].actions[].artifacts[].name')" >> $GITHUB_OUTPUT - artifact_checksum=$(echo ${RESPONSE} | jq -r '.data[].actions[].artifacts[].checksum') - echo "artifact_sha256=${artifact_checksum#sha256:}" >> $GITHUB_OUTPUT - env: - BROKER_URL: https://broker.io.nrs.gov.bc.ca - BROKER_JWT: ${{ secrets.<%= brokerJwt %> }} - SERVICE_PROJECT: ${{ env.SERVICE_PROJECT }} - SERVICE_NAME: ${{ env.SERVICE_NAME }} - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - fetch-tags: true - ref: ${{ github.ref }} - - name: Set up Java - uses: actions/setup-java@v4 - with: - java-version: '8' - distribution: 'temurin' - cache: maven - - name: Set download URL - id: set-download-url - run: | - sudo apt-get -qq install libxml2-utils - GROUP_ID=$(mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout --file <%= pomRoot %>pom.xml) - GROUP_ID_PATH="${GROUP_ID//.//}" - PACKAGE_TYPE=$(mvn help:evaluate -Dexpression=project.packaging -q -DforceStdout --file <%= pomRoot %>pom.xml) - ARTIFACT_NAME="${SERVICE_NAME}-${PROJECT_VERSION}.${PACKAGE_TYPE}" - DOWNLOAD_URL="${PACKAGE_REPO}/${GROUP_ID_PATH}/${SERVICE_NAME}/${PROJECT_VERSION}/${ARTIFACT_NAME}" - echo "${DOWNLOAD_URL}" - echo "download_url=$(echo ${DOWNLOAD_URL})" >> $GITHUB_OUTPUT - env: - SERVICE_NAME: ${{ env.SERVICE_NAME }} - PROJECT_VERSION: ${{ steps.set-tag-output.outputs.project_version }} - PACKAGE_REPO: ${{ env.PACKAGE_REPO }} - submit-job: - name: Submit job - if: | - always() && - ((needs.deploy-build.result == 'success' && needs.deploy-tag.result == 'skipped') || - (needs.deploy-build.result == 'skipped' && needs.deploy-tag.result == 'success')) - needs: [deploy-build, deploy-tag] - runs-on: ubuntu-latest - steps: - - name: Submit a job to Jenkins -<% if (gitHubPackages) { -%> - run: | - curl \ - --data-urlencode "token=${{ secrets.JENKINS_TOKEN }}" \ - --data-urlencode "githubToken=${{ secrets.GITHUB_TOKEN }}" \ - --data-urlencode "artifactSha256=${ARTIFACT_SHA256}" \ - --data-urlencode "projectVersion=${PROJECT_VERSION}" \ - --data-urlencode "gitBranch=${{ github.ref_name }}" \ - --data-urlencode "intentionId=${BUILD_GUID}" \ - --data-urlencode "gitTag=${{ (startsWith(github.ref, 'refs/tags/') && github.ref_name) || '' }}" \ - --data-urlencode "configBranch=${{ inputs.config_branch || '' }}" \ - --data-urlencode "downloadUrl=${DOWNLOAD_URL}" \ - --data-urlencode "downloadType=GITHUB" \ - -H "Connection: close" \ - ${{ env.URL }}/${{ env.JOB }} -<% } else { -%> - run: | - curl \ - --data-urlencode "token=${{ secrets.JENKINS_TOKEN }}" \ - --data-urlencode "githubToken=${{ secrets.GITHUB_TOKEN }}" \ - --data-urlencode "artifactSha256=${ARTIFACT_SHA256}" \ - --data-urlencode "projectVersion=${PROJECT_VERSION}" \ - --data-urlencode "gitBranch=${{ github.ref_name }}" \ - --data-urlencode "intentionId=${BUILD_GUID}" \ - --data-urlencode "gitTag=${{ (startsWith(github.ref, 'refs/tags/') && github.ref_name) || '' }}" \ - --data-urlencode "configBranch=${{ inputs.config_branch || '' }}" \ - --data-urlencode "downloadUrl=${DOWNLOAD_URL}" \ - --data-urlencode "downloadType=ARTIFACTORY" \ - -H "Connection: close" \ - ${{ env.URL }}/${{ env.JOB }} -<% } -%> - env: - PROJECT_VERSION: ${{ needs.deploy-build.outputs.project_version || needs.deploy-tag.outputs.project_version }} - BUILD_GUID: ${{ needs.deploy-build.outputs.build_guid || needs.deploy-tag.outputs.build_guid }} - BUILD_NUMBER: ${{ needs.deploy-build.outputs.build_number || needs.deploy-tag.outputs.build_number }} - ARTIFACT_SHA256: ${{ needs.deploy-build.outputs.artifact_sha256 || needs.deploy-tag.outputs.artifact_sha256 }} - DOWNLOAD_URL: ${{ needs.deploy-build.outputs.download_url || needs.deploy-tag.outputs.download_url }} - # The automatically generated GitHub token will expire when the workflow ends. We need to wait so the job has time to clone the repo - # and download the package - - name: Sleep - run: sleep 90s - shell: bash diff --git a/generators/gh-nodejs-build/templates/deployment-intention.json b/generators/gh-nodejs-build/templates/deployment-intention.json deleted file mode 100644 index 099b303..0000000 --- a/generators/gh-nodejs-build/templates/deployment-intention.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "event": { - "provider": "EVENT_PROVIDER", - "reason": "Job triggered", - "url": "JOB_URL" - }, - "actions": [ - { - "action": "server-access", - "id": "login", - "provision": ["token/self"], - "service": { - "name": "<%= serviceName %>", - "project": "<%= projectName %>", - "environment": "", - "target": { - "name": "jenkins-apps", - "project": "jenkins", - "environment": "production" - } - } - }, - { - "action": "package-configure", - "id": "configure", - "provision": ["token/self"], - "service": { - "name": "<%= serviceName %>", - "project": "<%= projectName %>", - "environment": "" - } - }, - { - "action": "package-installation", - "id": "install", - "provision": [], - "cloud": { - "target": { - "provider": "dxcas" - } - }, - "service": { - "name": "<%= serviceName %>", - "project": "<%= projectName %>", - "environment": "" - }, - "package": { - "version": "", - "buildGuid": "" - }, - "source": { - "action": "package-build#build" - } - } - ], - "user": { - "name": "USER_ID" - } -} \ No newline at end of file