From 5a554e1dc00d529459cc3ff6a647ebfcda8d60e3 Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Sun, 17 Dec 2023 10:18:54 +0000 Subject: [PATCH 01/20] ide: comment and improve launch config file --- .vscode/launch.json | 48 ++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 80f7e92d..4179de24 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ - { + { // PLAYGROUND "name": "Playground", "request": "launch", "type": "node", @@ -27,7 +27,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // ADD ISSUE TO PROJECT "name": "Add Issue To Project", "request": "launch", "type": "node", @@ -53,7 +53,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // ADD ITEM TO PROJECT "name": "Add Item To Project", "request": "launch", "type": "node", @@ -80,7 +80,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // CLOSE MILESTONE "name": "Close Milestone", "request": "launch", "type": "node", @@ -105,7 +105,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // GITHUB RELEASE DOES NOT EXIST "name": "GitHub Release Does Not Exist", "request": "launch", "type": "node", @@ -130,7 +130,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // LABEL IF HEAD BRANCH "name": "Label If Head Branch", "request": "launch", "type": "node", @@ -151,7 +151,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // MILESTONE EXISTS "name": "Milestone Exists", "request": "launch", "type": "node", @@ -177,7 +177,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // NUGET PACKAGE EXISTS "name": "NuGet Package Exists", "request": "launch", "type": "node", @@ -197,7 +197,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // PREPARE RELEASE "name": "Prepare Release", "request": "launch", "type": "node", @@ -223,7 +223,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // SEND RELEASE TWEET "name": "Send Release Tweet", "request": "launch", "type": "node", @@ -252,7 +252,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // SYNC BOT "name": "Sync Bot", "request": "launch", "type": "node", @@ -278,7 +278,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // SYNC ISSUE TO PR "name": "Sync Issue To PR", "request": "launch", "type": "node", @@ -304,7 +304,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // SYNC STATUS CHECK "name": "Sync Status Check", "request": "launch", "type": "node", @@ -330,7 +330,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // TRANSPILE README "name": "Transpile README", "request": "launch", "type": "node", @@ -353,7 +353,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // UPDATE CSHARP FILE "name": "Update CSharp File", "request": "launch", "type": "node", @@ -376,7 +376,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // UPDATE WORKFLOW VERSIONS "name": "Update Workflow Versions", "request": "launch", "type": "node", @@ -400,7 +400,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // WORKFLOW VERSION STATUS CHECK "name": "Workflow Version Status Check", "request": "launch", "type": "node", @@ -423,7 +423,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // VALIDATE EITHER TAG "name": "Validate Either Tag", "request": "launch", "type": "node", @@ -450,7 +450,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // VALIDATE PREVIEW TAG "name": "Validate Preview Tag", "request": "launch", "type": "node", @@ -477,7 +477,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // VALIDATE PROD TAG "name": "Validate Prod Tag", "request": "launch", "type": "node", @@ -504,7 +504,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // VALIDATE RELEASE NOTES "name": "Validate Release Notes", "request": "launch", "type": "node", @@ -530,7 +530,7 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { + { // VALIDATE VERSION "name": "Validate Version", "request": "launch", "type": "node", @@ -550,8 +550,8 @@ "runtimeExecutable": "${userHome}/.deno/bin/deno" } }, - { - "name": "Deno Check", + { // BUILD (DENO CHECK) + "name": "Build (Deno Check)", "request": "launch", "type": "node", "program": "${workspaceFolder}/.github/internal-cicd/scripts/deno-check.ts", From aad09397d081e32dad70b5bffc09b6494e6e62df Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Sun, 17 Dec 2023 10:24:46 +0000 Subject: [PATCH 02/20] deps: import walk module and refactor --- deps.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/deps.ts b/deps.ts index 7fef941e..eb146f17 100644 --- a/deps.ts +++ b/deps.ts @@ -1,5 +1,5 @@ // Deno Standard Library -import { existsSync } from "https://deno.land/std@0.207.0/fs/exists.ts"; +import { existsSync, walkSync } from "https://deno.land/std@0.207.0/fs/mod.ts"; import { extname, basename, resolve } from "https://deno.land/std@0.207.0/path/mod.ts"; import { isWindows } from "https://deno.land/std@0.207.0/path/_os.ts"; @@ -28,7 +28,8 @@ import { Directory, CLI, File, Path } from "./cicd/core/mod.ts"; ////////////////////////////////////////////////////////////////////////////////////////////// // Deno Standard Library -export { existsSync, extname, basename, resolve }; +export { existsSync, walkSync }; +export { extname, basename, resolve }; export { isWindows }; // KD CLIENTS From 3670203f3bd5126520b237949d7d127eccb3d559 Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 14:39:32 +0000 Subject: [PATCH 03/20] chore: add util funcs for dotnet sdk versions --- cicd/core/Utils.ts | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/cicd/core/Utils.ts b/cicd/core/Utils.ts index 59720231..bc2830bb 100644 --- a/cicd/core/Utils.ts +++ b/cicd/core/Utils.ts @@ -8,6 +8,9 @@ import { IssueModel, LabelModel, ProjectModel, PullRequestModel, UserModel } fro export class Utils { private static readonly prodVersionRegex = /^v([1-9]\d*|0)\.([1-9]\d*|0)\.([1-9]\d*|0)$/; private static readonly prevVersionRegex = /^v([1-9]\d*|0)\.([1-9]\d*|0)\.([1-9]\d*|0)(-preview\.([1-9]\d*))?$/; + private static readonly dotnetSDKVersionRegex = /([1-9]\d*|0)\.([1-9]\d*|0)\.([1-9]\d*|0)/gm; + private static readonly csprojTargetFrameworkVersionRegex = /net([1-9]\d*|0)(\.([1-9]\d*|0)|)(\.([1-9]\d*|0)|)/gm; + private static readonly targetFrameworkRegex = /\s*net.+\s*<\/TargetFramework\s*>/gm; private static readonly featureBranchRegex = /^feature\/[1-9][0-9]*-(?!-)[a-z-]+/gm; /** @@ -279,6 +282,36 @@ export class Utils { return !Utils.validPreviewVersion(version); } + /** + * Returns a value indicating whether or not the given {@link version} is a valid version. + * @param version The version to check. + * @returns True if the version is a valid version, otherwise false. + */ + public static isValidDotnetSDKVersion(version: string): boolean { + return this.dotnetSDKVersionRegex.test(version.trim().toLowerCase()); + } + + /** + * Gets the first occurrence of a dotnet target framework version found in the given {@link csProjFileData}. + * @param csProjFileData The csproj file data that might contain the target framework version. + * @returns The dotnet SDK version. + */ + public static getCSProjTargetFrameworkVersion(csProjFileData: string): string { + const tagMatches = csProjFileData.match(this.targetFrameworkRegex); + + const targetFrameworkTags = tagMatches === null || tagMatches.length === 0 + ? [] + : [...tagMatches]; + + if (targetFrameworkTags.length === 0) { + throw new Error("Could not find any target framework XML tags in the given csproj file data."); + } + + const matches: string[] = targetFrameworkTags[0].match(this.csprojTargetFrameworkVersionRegex) ?? []; + + return matches.length > 0 ? matches[0] : ""; + } + /** * Returns a number that is clamped between the given {@link min} and {@link max} values. * @param value The value to clamp. From 0172178294a9119f233f78b1effa485bc1d18dd4 Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 14:39:00 +0000 Subject: [PATCH 04/20] refactor: improve csharp version service by using new util funcs --- cicd/core/Services/CSharpVersionService.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cicd/core/Services/CSharpVersionService.ts b/cicd/core/Services/CSharpVersionService.ts index f0e32d19..5c38d829 100644 --- a/cicd/core/Services/CSharpVersionService.ts +++ b/cicd/core/Services/CSharpVersionService.ts @@ -7,7 +7,6 @@ import { ReleaseType } from "../Enums.ts"; * Updates the version of a C# project file directly on a branch of a repository. */ export class CSharpVersionService extends VersionServiceBase { - private readonly versionRegex = /([1-9]\d*|0)\.([1-9]\d*|0)\.([1-9]\d*|0)(-preview\.([1-9]\d*))?/gm; private readonly versionTagRegex = /.*<\/Version\s*>/gm; private readonly fileVersionTagRegex = /.*<\/FileVersion\s*>/gm; @@ -71,7 +70,7 @@ export class CSharpVersionService extends VersionServiceBase { * @inheritdoc */ public versionIsValid(version: string): boolean { - return this.versionRegex.test(version); + return Utils.isValidDotnetSDKVersion(version); } /** @@ -98,7 +97,7 @@ export class CSharpVersionService extends VersionServiceBase { const versionTag = fileData.match(this.versionTagRegex)?.[0] ?? ""; // Get the version value from the version tag - const versionTagValue = versionTag.match(this.versionRegex)?.[0] ?? ""; + const versionTagValue = Utils.getCSProjTargetFrameworkVersion(versionTag); // If the tag value matches the new version return versionTagValue === version; @@ -114,7 +113,7 @@ export class CSharpVersionService extends VersionServiceBase { const versionTag = fileData.match(this.fileVersionTagRegex)?.[0] ?? ""; // Get the version value from the version tag - const versionTagValue = versionTag.match(this.versionRegex)?.[0] ?? ""; + const versionTagValue = Utils.getCSProjTargetFrameworkVersion(versionTag); // If the tag value matches the new version return versionTagValue === version; From ea5f51663db934bd48ff5ac1bf3bbfd9341c12fd Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 14:38:13 +0000 Subject: [PATCH 05/20] ci: update all deno versions to use repo variable --- .github/workflows/add-item-to-project.yml | 2 +- .github/workflows/dotnet-lib-release.yml | 2 +- .github/workflows/initial-manual-sync.yml | 2 +- .github/workflows/lint-status-check.yml | 2 +- .github/workflows/nuget-package-does-not-exist.yml | 2 +- .github/workflows/prepare-release.yml | 2 +- .github/workflows/sync-bot.yml | 2 +- .github/workflows/validate-csharp-version.yml | 2 +- .github/workflows/validate-github-release.yml | 2 +- .github/workflows/validate-milestone-status.yml | 2 +- .github/workflows/validate-tag.yml | 2 +- .github/workflows/workflow-version-status-check.yml | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/add-item-to-project.yml b/.github/workflows/add-item-to-project.yml index fc4c314d..37d1c20d 100644 --- a/.github/workflows/add-item-to-project.yml +++ b/.github/workflows/add-item-to-project.yml @@ -66,7 +66,7 @@ jobs: - name: Set Up Deno uses: denoland/setup-deno@v1 with: - deno-version: v1.x + deno-version: ${{ vars.DENO_VERSION }} - name: Add To Project run: | diff --git a/.github/workflows/dotnet-lib-release.yml b/.github/workflows/dotnet-lib-release.yml index e45e4eb9..5b2b26dc 100644 --- a/.github/workflows/dotnet-lib-release.yml +++ b/.github/workflows/dotnet-lib-release.yml @@ -281,7 +281,7 @@ jobs: - name: Set Up Deno uses: denoland/setup-deno@v1 with: - deno-version: v1.x + deno-version: ${{ vars.DENO_VERSION }} - name: Create Script URL id: script-url diff --git a/.github/workflows/initial-manual-sync.yml b/.github/workflows/initial-manual-sync.yml index d7ee7be0..d674bf9a 100644 --- a/.github/workflows/initial-manual-sync.yml +++ b/.github/workflows/initial-manual-sync.yml @@ -82,7 +82,7 @@ jobs: if: ${{ steps.skip-checking.outputs.skip == 'false' }} uses: denoland/setup-deno@v1 with: - deno-version: v1.x + deno-version: ${{ vars.DENO_VERSION }} - name: Run Sync if: ${{ steps.skip-checking.outputs.skip == 'false' }} diff --git a/.github/workflows/lint-status-check.yml b/.github/workflows/lint-status-check.yml index 8b9d003e..2bc924a3 100644 --- a/.github/workflows/lint-status-check.yml +++ b/.github/workflows/lint-status-check.yml @@ -22,7 +22,7 @@ jobs: - name: Set Up Deno uses: denoland/setup-deno@v1 with: - deno-version: v1.x + deno-version: ${{ vars.DENO_VERSION }} - name: Run Linting run: deno lint diff --git a/.github/workflows/nuget-package-does-not-exist.yml b/.github/workflows/nuget-package-does-not-exist.yml index fdf32710..9b9355e2 100644 --- a/.github/workflows/nuget-package-does-not-exist.yml +++ b/.github/workflows/nuget-package-does-not-exist.yml @@ -55,7 +55,7 @@ jobs: - name: Set Up Deno uses: denoland/setup-deno@v1 with: - deno-version: v1.x + deno-version: ${{ vars.DENO_VERSION }} - name: Package Does Not Exist run: | diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 0e1c6b29..b2890c3c 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -84,7 +84,7 @@ jobs: - name: Set Up Deno uses: denoland/setup-deno@v1 with: - deno-version: v1.x + deno-version: ${{ vars.DENO_VERSION }} - name: Generate Release Notes run: | diff --git a/.github/workflows/sync-bot.yml b/.github/workflows/sync-bot.yml index 46ce3b93..eb8056a8 100644 --- a/.github/workflows/sync-bot.yml +++ b/.github/workflows/sync-bot.yml @@ -20,7 +20,7 @@ jobs: - name: Set Up Deno uses: denoland/setup-deno@v1 with: - deno-version: v1.x + deno-version: ${{ vars.DENO_VERSION }} - name: Run Sync Bot (Issue Change) run: | diff --git a/.github/workflows/validate-csharp-version.yml b/.github/workflows/validate-csharp-version.yml index 9d6fe4a2..3301fa91 100644 --- a/.github/workflows/validate-csharp-version.yml +++ b/.github/workflows/validate-csharp-version.yml @@ -75,7 +75,7 @@ jobs: - name: Set Up Deno uses: denoland/setup-deno@v1 with: - deno-version: v1.x + deno-version: ${{ vars.DENO_VERSION }} - name: Validate Version id: validate-version diff --git a/.github/workflows/validate-github-release.yml b/.github/workflows/validate-github-release.yml index 72628acd..9435c618 100644 --- a/.github/workflows/validate-github-release.yml +++ b/.github/workflows/validate-github-release.yml @@ -68,7 +68,7 @@ jobs: - name: Set Up Deno uses: denoland/setup-deno@v1 with: - deno-version: v1.x + deno-version: ${{ vars.DENO_VERSION }} - name: GitHub Release Does Not Exist run: | diff --git a/.github/workflows/validate-milestone-status.yml b/.github/workflows/validate-milestone-status.yml index d42650a1..9e8a70e7 100644 --- a/.github/workflows/validate-milestone-status.yml +++ b/.github/workflows/validate-milestone-status.yml @@ -67,7 +67,7 @@ jobs: - name: Set Up Deno uses: denoland/setup-deno@v1 with: - deno-version: v1.x + deno-version: ${{ vars.DENO_VERSION }} - name: Create Script URL id: script-url diff --git a/.github/workflows/validate-tag.yml b/.github/workflows/validate-tag.yml index 7830bc20..5528c2e3 100644 --- a/.github/workflows/validate-tag.yml +++ b/.github/workflows/validate-tag.yml @@ -80,7 +80,7 @@ jobs: - name: Set Up Deno uses: denoland/setup-deno@v1 with: - deno-version: v1.x + deno-version: ${{ vars.DENO_VERSION }} - name: Validate Tag run: | diff --git a/.github/workflows/workflow-version-status-check.yml b/.github/workflows/workflow-version-status-check.yml index e0321c26..5cdeeca0 100644 --- a/.github/workflows/workflow-version-status-check.yml +++ b/.github/workflows/workflow-version-status-check.yml @@ -22,7 +22,7 @@ jobs: - name: Set Up Deno uses: denoland/setup-deno@v1 with: - deno-version: v1.x + deno-version: ${{ vars.DENO_VERSION }} - name: Run Status Check Script run: | From fc7ab4361f17769cbc8e7f6130fcb482458a7992 Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 15:10:18 +0000 Subject: [PATCH 06/20] ci,refactor: rearrange workflow inputs and input usage --- .github/workflows/build-csharp-project.yml | 12 ++++++------ .github/workflows/run-csharp-tests.yml | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build-csharp-project.yml b/.github/workflows/build-csharp-project.yml index 2c56865d..9e59e0ac 100644 --- a/.github/workflows/build-csharp-project.yml +++ b/.github/workflows/build-csharp-project.yml @@ -31,16 +31,16 @@ on: description: The type of machine to run the job on. type: string default: ubuntu-latest - checkout-ref: - required: false - description: The git reference to checkout the code at. - type: string - default: ${{ github.ref }} checkout-repository: required: false description: The git repository to checkout the code from. type: string default: ${{ github.repository }} + checkout-ref: + required: false + description: The git reference to checkout the code at. + type: string + default: ${{ github.ref }} secrets: cicd-pat: description: "The GitHub Personal Access Token (PAT) used to authenticate to the GitHub API." @@ -105,8 +105,8 @@ jobs: steps: - uses: actions/checkout@v4 with: - ref: ${{ inputs.checkout-ref }} repository: ${{ inputs.checkout-repository }} + ref: ${{ inputs.checkout-ref }} - name: Setup .NET SDK ${{ inputs.net-sdk-version }} uses: actions/setup-dotnet@v3 diff --git a/.github/workflows/run-csharp-tests.yml b/.github/workflows/run-csharp-tests.yml index 3f12ad96..fe9e707b 100644 --- a/.github/workflows/run-csharp-tests.yml +++ b/.github/workflows/run-csharp-tests.yml @@ -30,16 +30,16 @@ on: description: The type of machine to run the job on. type: string default: ubuntu-latest - checkout-ref: - required: false - description: The git reference to checkout the code at. - type: string - default: ${{ github.ref }} checkout-repository: required: false description: The git repository to checkout the code from. type: string default: ${{ github.repository }} + checkout-ref: + required: false + description: The git reference to checkout the code at. + type: string + default: ${{ github.ref }} secrets: cicd-pat: description: "The GitHub Personal Access Token (PAT) used to authenticate to the GitHub API." @@ -107,8 +107,8 @@ jobs: steps: - uses: actions/checkout@v4 with: - ref: ${{ inputs.checkout-ref }} repository: ${{ inputs.checkout-repository }} + ref: ${{ inputs.checkout-ref }} - uses: actions/setup-dotnet@v3 with: From bb783abb5c4790e1d570f4d08af72fcae25bf8a6 Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 15:35:58 +0000 Subject: [PATCH 07/20] ci,refactor: change emoji of reusuable workflows --- .github/workflows/add-item-to-project.yml | 2 +- .github/workflows/build-csharp-project.yml | 4 ++-- .github/workflows/dotnet-action-release.yml | 4 ++-- .github/workflows/dotnet-lib-release.yml | 4 ++-- .github/workflows/initial-manual-sync.yml | 4 ++-- .github/workflows/nuget-package-does-not-exist.yml | 4 ++-- .github/workflows/prepare-release.yml | 2 +- .github/workflows/resolve-csharp-proj-file.yml | 2 +- .github/workflows/run-csharp-tests.yml | 2 +- .github/workflows/validate-csharp-version.yml | 2 +- .github/workflows/validate-github-release.yml | 2 +- .github/workflows/validate-milestone-status.yml | 2 +- .github/workflows/validate-tag.yml | 2 +- 13 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/add-item-to-project.yml b/.github/workflows/add-item-to-project.yml index 37d1c20d..0a454112 100644 --- a/.github/workflows/add-item-to-project.yml +++ b/.github/workflows/add-item-to-project.yml @@ -1,4 +1,4 @@ -name: Add Issue To Project +name: ⚙️Add Issue To Project defaults: diff --git a/.github/workflows/build-csharp-project.yml b/.github/workflows/build-csharp-project.yml index 9e59e0ac..fc9998cb 100644 --- a/.github/workflows/build-csharp-project.yml +++ b/.github/workflows/build-csharp-project.yml @@ -1,5 +1,5 @@ -name: Build C# Project -run-name: Build Project (${{ inputs.project-name }}) +name: ⚙️Build C# Project +run-name: ⚙️Build Project (${{ inputs.project-name }}) defaults: diff --git a/.github/workflows/dotnet-action-release.yml b/.github/workflows/dotnet-action-release.yml index afbee4ee..516d5d8b 100644 --- a/.github/workflows/dotnet-action-release.yml +++ b/.github/workflows/dotnet-action-release.yml @@ -1,5 +1,5 @@ -name: 🚀Perform DotNet Action Release -run-name: Perform ${{ inputs.release-type }} Release (${{ inputs.build-config }} Build) +name: ⚙️Perform DotNet Action Release +run-name: ⚙️Perform ${{ inputs.release-type }} Release (${{ inputs.build-config }} Build) defaults: diff --git a/.github/workflows/dotnet-lib-release.yml b/.github/workflows/dotnet-lib-release.yml index 5b2b26dc..f767baa5 100644 --- a/.github/workflows/dotnet-lib-release.yml +++ b/.github/workflows/dotnet-lib-release.yml @@ -1,5 +1,5 @@ -name: 🚀Perform DotNet Lib Release -run-name: Perform ${{ inputs.release-type }} Release (${{ inputs.build-config }} Build) +name: ⚙️Perform DotNet Lib Release +run-name: ⚙️Perform ${{ inputs.release-type }} Release (${{ inputs.build-config }} Build) defaults: diff --git a/.github/workflows/initial-manual-sync.yml b/.github/workflows/initial-manual-sync.yml index d674bf9a..b27dae87 100644 --- a/.github/workflows/initial-manual-sync.yml +++ b/.github/workflows/initial-manual-sync.yml @@ -1,5 +1,5 @@ -name: 🔄️Sync PR To Issue -run-name: 🔄️Sync PR To Issue (${{ inputs.sync-type }}) +name: ⚙️Sync PR To Issue +run-name: ⚙️Sync PR To Issue (${{ inputs.sync-type }}) defaults: diff --git a/.github/workflows/nuget-package-does-not-exist.yml b/.github/workflows/nuget-package-does-not-exist.yml index 9b9355e2..99a6d995 100644 --- a/.github/workflows/nuget-package-does-not-exist.yml +++ b/.github/workflows/nuget-package-does-not-exist.yml @@ -1,5 +1,5 @@ -name: Check NuGet Package -run-name: Check NuGet Package (${{ inputs.version }}) +name: ⚙️Check NuGet Package +run-name: ⚙️Check NuGet Package (${{ inputs.version }}) defaults: diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index b2890c3c..94bfc610 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -1,4 +1,4 @@ -name: 🚁Prepare Release +name: ⚙️Prepare Release defaults: diff --git a/.github/workflows/resolve-csharp-proj-file.yml b/.github/workflows/resolve-csharp-proj-file.yml index 5a482125..11d6d985 100644 --- a/.github/workflows/resolve-csharp-proj-file.yml +++ b/.github/workflows/resolve-csharp-proj-file.yml @@ -1,4 +1,4 @@ -name: Resolve CSharp Project File Path +name: ⚙️Resolve CSharp Project File Path defaults: diff --git a/.github/workflows/run-csharp-tests.yml b/.github/workflows/run-csharp-tests.yml index fe9e707b..22505546 100644 --- a/.github/workflows/run-csharp-tests.yml +++ b/.github/workflows/run-csharp-tests.yml @@ -1,4 +1,4 @@ -name: Unit C# Tests +name: ⚙️Unit C# Tests defaults: diff --git a/.github/workflows/validate-csharp-version.yml b/.github/workflows/validate-csharp-version.yml index 3301fa91..643b5282 100644 --- a/.github/workflows/validate-csharp-version.yml +++ b/.github/workflows/validate-csharp-version.yml @@ -1,4 +1,4 @@ -name: Validate CSharp Version +name: ⚙️Validate CSharp Version defaults: diff --git a/.github/workflows/validate-github-release.yml b/.github/workflows/validate-github-release.yml index 9435c618..58bacfbf 100644 --- a/.github/workflows/validate-github-release.yml +++ b/.github/workflows/validate-github-release.yml @@ -1,4 +1,4 @@ -name: Validate GitHub Release +name: ⚙️Validate GitHub Release defaults: diff --git a/.github/workflows/validate-milestone-status.yml b/.github/workflows/validate-milestone-status.yml index 9e8a70e7..51496ce6 100644 --- a/.github/workflows/validate-milestone-status.yml +++ b/.github/workflows/validate-milestone-status.yml @@ -1,4 +1,4 @@ -name: Validate Release Notes +name: ⚙️Validate Release Notes defaults: diff --git a/.github/workflows/validate-tag.yml b/.github/workflows/validate-tag.yml index 5528c2e3..e882ff27 100644 --- a/.github/workflows/validate-tag.yml +++ b/.github/workflows/validate-tag.yml @@ -1,4 +1,4 @@ -name: Validate Tag +name: ⚙️Validate Tag defaults: From c585b23b6bc9be2805038f18089be5fe17b8d811 Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 15:43:30 +0000 Subject: [PATCH 08/20] chore: create func to check if a csproj contains the target framework tag --- cicd/core/Utils.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cicd/core/Utils.ts b/cicd/core/Utils.ts index bc2830bb..7c39ddd5 100644 --- a/cicd/core/Utils.ts +++ b/cicd/core/Utils.ts @@ -291,6 +291,15 @@ export class Utils { return this.dotnetSDKVersionRegex.test(version.trim().toLowerCase()); } + /** + * Returns a value indicating whether or not the given {@link csProjFileData} contains the target framework XML tag. + * @param csProjFileData The csproj file data that might contain the target framework version. + * @returns True if the target framework XML tag exists in the given {@link csProjFileData}, otherwise false. + */ + public static targetFrameworkXMLExists(csProjFileData: string): boolean { + return this.targetFrameworkRegex.test(csProjFileData); + } + /** * Gets the first occurrence of a dotnet target framework version found in the given {@link csProjFileData}. * @param csProjFileData The csproj file data that might contain the target framework version. From f991561c7ba26932f58d7c74b6f55d1075a7e554 Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 15:44:27 +0000 Subject: [PATCH 09/20] feat: create ability to validate a dotnet projects sdk version setup --- .github/workflows/validate-sdk-setup.yml | 71 ++++++++ cicd/scripts/mod.ts | 1 + .../scripts/runners/ValidateSDKSetupRunner.ts | 159 ++++++++++++++++++ cicd/scripts/validate-sdk-setup.ts | 16 ++ 4 files changed, 247 insertions(+) create mode 100644 .github/workflows/validate-sdk-setup.yml create mode 100644 cicd/scripts/runners/ValidateSDKSetupRunner.ts create mode 100644 cicd/scripts/validate-sdk-setup.ts diff --git a/.github/workflows/validate-sdk-setup.yml b/.github/workflows/validate-sdk-setup.yml new file mode 100644 index 00000000..75935237 --- /dev/null +++ b/.github/workflows/validate-sdk-setup.yml @@ -0,0 +1,71 @@ +name: ⚙️Validate SDK Setup + + +defaults: + run: + shell: pwsh + + +on: + workflow_call: + inputs: + repo-name: + required: true + description: The name of the GitHub repository. + type: string + checkout-repository: + required: false + description: The git repository to checkout the code from. + type: string + default: ${{ github.repository }} + checkout-ref: + required: false + description: The git reference to checkout the code at. + type: string + default: ${{ github.ref }} + + +jobs: + validate_sdk_setup: + name: Validate SDK Setup + runs-on: ubuntu-latest + steps: + - name: Validate + run: | + $repoName = "${{ inputs.repo-name }}"; + + if ($repoName -eq "") { + Write-Host "The repository name is required."; + exit 1; + } + + - name: Checkout Repository + uses: actions/checkout@v4 + with: + repository: ${{ inputs.checkout-repository }} + ref: ${{ inputs.checkout-ref }} + + - name: Set Up Deno + uses: denoland/setup-deno@v1 + with: + deno-version: ${{ vars.DENO_VERSION }} + + - name: Generate Release Notes + run: | + # Construct the URL to the organizations CICD scripts + $scriptUrl = "${{ vars.SCRIPT_BASE_URL }}/${{ vars.CICD_SCRIPTS_VERSION }}/${{ vars.SCRIPT_RELATIVE_DIR_PATH }}"; + $scriptUrl = $scriptUrl.Replace("\", "/").Replace("//", "/"); + $scriptUrl = $scriptUrl.EndsWith("/") ? $scriptUrl.Substring(0, $scriptUrl.Length - 1) : $scriptUrl; + $scriptUrl = "$scriptUrl/validate-sdk-setup.ts"; + + <# Deno Args: + 1. Organization name + 2. Project name + 3. PAT + #> + deno run ` + --allow-read --allow-net ` + "$scriptUrl" ` + "${{ vars.ORGANIZATION_NAME }}" ` + "${{ inputs.repo-name }}" ` + "${{ secrets.cicd-pat }}"; diff --git a/cicd/scripts/mod.ts b/cicd/scripts/mod.ts index 92a1a242..17a6cd82 100644 --- a/cicd/scripts/mod.ts +++ b/cicd/scripts/mod.ts @@ -14,3 +14,4 @@ import syncPrToIssueExecutor from "./sync-pr-to-issue.ts"; import transpileReadMeExecutor from "./transpile-readme.ts"; import validateTagExecutor from "./validate-tag.ts"; import validateVersionExecutor from "./validate-version.ts"; +import validateSDKSetupExecutor from "./validate-sdk-setup.ts"; diff --git a/cicd/scripts/runners/ValidateSDKSetupRunner.ts b/cicd/scripts/runners/ValidateSDKSetupRunner.ts new file mode 100644 index 00000000..b2583e21 --- /dev/null +++ b/cicd/scripts/runners/ValidateSDKSetupRunner.ts @@ -0,0 +1,159 @@ +import { RepoClient, walkSync } from "../../../deps.ts"; +import { Utils } from "../../core/Utils.ts"; +import { ScriptRunner } from "./ScriptRunner.ts"; + +/** + * Validates that a dotnet SDK setup for a dotnet project is correct. + */ +export class ValidateSDKSetupRunner extends ScriptRunner { + private readonly repoClient: RepoClient; + + /** + * Initializes a new instance of the {@link ValidateSDKSetupRunner} class. + * @param args The arguments to process. + */ + constructor(args: string[]) { + super(args); + + const [repoOwner, repoName] = this.args; + + this.repoClient = new RepoClient(repoOwner, repoName, this.token); + } + + public async run(): Promise { + const baseDirPath = Deno.cwd(); + + // Find all of the csproj files for inspection + const entries = walkSync(baseDirPath, { + includeDirs: false, + includeFiles: true, + exts: [".csproj"], + }); + + let dotnetSDKVersion = (await this.repoClient.getVariables()) + .find((repoVar) => repoVar.name === "NET_SDK_VERSION")?.value.trim(); + + if (Utils.isNothing(dotnetSDKVersion)) { + throw new Error("The NET_SDK_VERSION variable is not defined."); + } + + dotnetSDKVersion = dotnetSDKVersion.startsWith("v") + ? dotnetSDKVersion.substring(1) + : dotnetSDKVersion; + + if (!Utils.isValidDotnetSDKVersion(dotnetSDKVersion)) { + Utils.printAsGitHubError(`The NET_SDK_VERSION variable is not a valid dotnet version: ${dotnetSDKVersion}`); + Deno.exit(1); + } + + const csProFiles = [...entries].map((entry) => entry.path.replaceAll("\\", "/")) + .filter((path) => !/(\/bin\/|\/obj\/)/.test(path)); + + const filesWithoutTargetFramework: string[] = []; + const nonMatchingVersions: [string, string][] = []; + + for (const csProjFile of csProFiles) { + const fileData = Deno.readTextFileSync(csProjFile); + + let targetFrameworkVersion = ""; + + // If the target framework XML exists, check the version value. + if (Utils.targetFrameworkXMLExists(fileData)) { + try { + targetFrameworkVersion = Utils.getCSProjTargetFrameworkVersion(fileData).replace("net", ""); + } catch (error) { + nonMatchingVersions.push([csProjFile, error.message]); + } + + const versionsMatch = this.versionsMatch(dotnetSDKVersion, targetFrameworkVersion); + + if (versionsMatch) { + continue; + } + + const errorMsg = `The target framework version in the csproj file '${csProjFile}' does not match the repo` + + ` variable NET_SDK_VERSION.`; + nonMatchingVersions.push([csProjFile, errorMsg]) + } else { + filesWithoutTargetFramework.push(csProjFile); + } + } + + // If there are any issues with any of the files, print them out. + if (filesWithoutTargetFramework.length > 0 || nonMatchingVersions.length > 0) { + filesWithoutTargetFramework.forEach(fileWithout => { + Utils.printAsGitHubError(`The file '${fileWithout}' does not have a target framework defined.`); + }); + + nonMatchingVersions.forEach(nonMatchingVersion => { + const errorMsg = `The file '${nonMatchingVersion[0]}' has a target framework version that does not ` + + `match the NET_SDK_VERSION variable.\n${nonMatchingVersion[1]}`; + Utils.printAsGitHubError(errorMsg); + }); + + Deno.exit(1); + } + } + + /** + * @inheritdoc + */ + protected async validateArgs(args: string[]): Promise { + const [repoOwner, repoName] = args; + + // Validate that the repo exists + const repoExists = await this.repoClient.exists(); + + if (!repoExists) + { + throw new Error(`The repo ${repoOwner}/${repoName} does not exist.`); + } + + return Promise.resolve(); + } + + /** + * @inheritdoc + */ + protected mutateArgs(args: string[]): string[] { + let [repoOwner, repoName] = args; + + repoOwner = repoOwner.trim(); + repoName = repoName.trim(); + + return [repoOwner, repoName]; + } + + /** + * Gets a value indicating whether or not the {@link repoVarSections} and {@link csprojVersion} versions match. + * @param repoVarVersion The version from the repository variable. + * @param csprojVersion The version from the csproj file. + * @returns True if the versions match, false otherwise. + * @remarks This function takes the csproj version as precedence in regards to the major, minor, and patch sections. + * If the csproj version does not have a minor or path version, the result will be true as long as the major version + * of both values match. + */ + private versionsMatch(repoVarVersion: string, csprojVersion: string): boolean { + repoVarVersion = repoVarVersion.trim().toLowerCase(); + csprojVersion = csprojVersion.trim().toLowerCase(); + + const csprojSections = csprojVersion.split("."); + const repoVarSections = repoVarVersion.split("."); + + if (repoVarSections.length < 3) { + Utils.printAsGitHubError(`The NET_SDK_VERSION variable does not have a major, minor, and patch section.`); + Deno.exit(1); + } + + for (let i = 0; i < csprojSections.length; i++) { + const targetVersionSection = csprojSections[i]; + const repoVarSection = repoVarSections[i]; + + if (targetVersionSection !== repoVarSection) { + return false; + } + } + + return true; + } +} diff --git a/cicd/scripts/validate-sdk-setup.ts b/cicd/scripts/validate-sdk-setup.ts new file mode 100644 index 00000000..9cd0d522 --- /dev/null +++ b/cicd/scripts/validate-sdk-setup.ts @@ -0,0 +1,16 @@ +import { ValidateSDKSetupRunner } from "./runners/ValidateSDKSetupRunner.ts"; + +const validateSDKSetupExecutor = async () => { + const runner = new ValidateSDKSetupRunner(Deno.args); + + try { + await runner.run(); + } catch (error) { + console.error(error); + Deno.exit(1); + } +} + +validateSDKSetupExecutor(); + +export default validateSDKSetupExecutor; From dde06805bb3e5375ae4ab10ef551bbb5398641f7 Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 15:44:40 +0000 Subject: [PATCH 10/20] ide: add launch config for manual testing --- .vscode/launch.json | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 4179de24..11d1098f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -574,6 +574,31 @@ "linux": { "runtimeExecutable": "${userHome}/.deno/bin/deno" }, - } + }, + { // VALIDATE SDK SETUP + "name": "Validate SDK Setup", + "request": "launch", + "type": "node", + "program": "${workspaceFolder}/cicd/scripts/validate-sdk-setup.ts", + "cwd": "${workspaceFolder}", + "runtimeArgs": [ + "run", + "--inspect-wait", + "--allow-read", + "--allow-net" + ], + "args": [ + "KinsonDigital", + "Infrastructure", + "${env:CICD_TOKEN}", + ], + "attachSimplePort": 9229, + "windows": { + "runtimeExecutable": "${userHome}\\.deno\\bin\\deno.exe" + }, + "linux": { + "runtimeExecutable": "${userHome}/.deno/bin/deno" + } + }, ] } From aad43d401d2ad1bd7c561bfd87c2a43c2a780f4b Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 15:44:47 +0000 Subject: [PATCH 11/20] deps: update deno lock --- deno.lock | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/deno.lock b/deno.lock index 7e1412b1..97f119ee 100644 --- a/deno.lock +++ b/deno.lock @@ -153,7 +153,19 @@ "https://deno.land/std@0.204.0/testing/mock.ts": "6576b4aa55ee20b1990d656a78fff83599e190948c00e9f25a7f3ac5e9d6492d", "https://deno.land/std@0.207.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee", "https://deno.land/std@0.207.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56", + "https://deno.land/std@0.207.0/fs/_util.ts": "fbf57dcdc9f7bc8128d60301eece608246971a7836a3bb1e78da75314f08b978", + "https://deno.land/std@0.207.0/fs/copy.ts": "ca19e4837965914471df38fbd61e16f9e8adfe89f9cffb0c83615c83ea3fc2bf", + "https://deno.land/std@0.207.0/fs/empty_dir.ts": "7fba29ef2d03f3503cd512616efc0535984cf1bbe7ca9d098e8b4d0d88910120", + "https://deno.land/std@0.207.0/fs/ensure_dir.ts": "dc64c4c75c64721d4e3fb681f1382f803ff3d2868f08563ff923fdd20d071c40", + "https://deno.land/std@0.207.0/fs/ensure_file.ts": "39ac83cc283a20ec2735e956adf5de3e8a3334e0b6820547b5772f71c49ae083", + "https://deno.land/std@0.207.0/fs/ensure_link.ts": "c15e69c48556d78aae31b83e0c0ece04b7b8bc0951412f5b759aceb6fde7f0ac", + "https://deno.land/std@0.207.0/fs/ensure_symlink.ts": "b389c8568f0656d145ac7ece472afe710815cccbb2ebfd19da7978379ae143fe", + "https://deno.land/std@0.207.0/fs/eol.ts": "8565e1e076c5baced170236617150a7833668658e000205d896fc54084309ce1", "https://deno.land/std@0.207.0/fs/exists.ts": "cb59a853d84871d87acab0e7936a4dac11282957f8e195102c5a7acb42546bb8", + "https://deno.land/std@0.207.0/fs/expand_glob.ts": "4f98c508fc9e40d6311d2f7fd88aaad05235cc506388c22dda315e095305811d", + "https://deno.land/std@0.207.0/fs/mod.ts": "bc3d0acd488cc7b42627044caf47d72019846d459279544e1934418955ba4898", + "https://deno.land/std@0.207.0/fs/move.ts": "b4f8f46730b40c32ea3c0bc8eb0fd0e8139249a698883c7b3756424cf19785c9", + "https://deno.land/std@0.207.0/fs/walk.ts": "c1e6b43f72a46e89b630140308bd51a4795d416a416b4cfb7cd4bd1e25946723", "https://deno.land/std@0.207.0/path/_common/assert_path.ts": "061e4d093d4ba5aebceb2c4da3318bfe3289e868570e9d3a8e327d91c2958946", "https://deno.land/std@0.207.0/path/_common/basename.ts": "0d978ff818f339cd3b1d09dc914881f4d15617432ae519c1b8fdc09ff8d3789a", "https://deno.land/std@0.207.0/path/_common/common.ts": "9e4233b2eeb50f8b2ae10ecc2108f58583aea6fd3e8907827020282dc2b76143", @@ -175,6 +187,7 @@ "https://deno.land/std@0.207.0/path/extname.ts": "2da4e2490f3b48b7121d19fb4c91681a5e11bd6bd99df4f6f47d7a71bb6ecdf2", "https://deno.land/std@0.207.0/path/format.ts": "3457530cc85d1b4bab175f9ae73998b34fd456c830d01883169af0681b8894fb", "https://deno.land/std@0.207.0/path/from_file_url.ts": "e7fa233ea1dff9641e8d566153a24d95010110185a6f418dd2e32320926043f8", + "https://deno.land/std@0.207.0/path/glob.ts": "29331e11dcd2b3d0b1a7673e02c589347075aae0c837e4a673c000cd9d741512", "https://deno.land/std@0.207.0/path/glob_to_regexp.ts": "74d7448c471e293d03f05ccb968df4365fed6aaa508506b6325a8efdc01d8271", "https://deno.land/std@0.207.0/path/is_absolute.ts": "67232b41b860571c5b7537f4954c88d86ae2ba45e883ee37d3dec27b74909d13", "https://deno.land/std@0.207.0/path/is_glob.ts": "567dce5c6656bdedfc6b3ee6c0833e1e4db2b8dff6e62148e94a917f289c06ad", From 7e5142da81504f1705b1f06bc2f78db9112ef6a6 Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 15:52:14 +0000 Subject: [PATCH 12/20] ci: add dotnet sdk setup validation to dotnet release workflows --- .github/workflows/dotnet-action-release.yml | 9 +++++++++ .github/workflows/dotnet-lib-release.yml | 20 +++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet-action-release.yml b/.github/workflows/dotnet-action-release.yml index 516d5d8b..5d8d6e4d 100644 --- a/.github/workflows/dotnet-action-release.yml +++ b/.github/workflows/dotnet-action-release.yml @@ -177,6 +177,14 @@ jobs: cicd-pat: "${{ secrets.cicd-pat }}" + validate_sdk_setup: + name: Validate SDK Setup + needs: print_validate_workflow + uses: KinsonDigital/Infrastructure/.github/workflows/validate-sdk-setup.yml@v13.5.0 + with: + repo-name: "${{ inputs.project-name }}" + + validate_release_notes_exist: name: Validate Release Notes Exist needs: validate_version @@ -248,6 +256,7 @@ jobs: validate_branch, validate_version, validate_tag, + validate_sdk_setup, validate_release_notes_exist, validate_github_release, build_project, diff --git a/.github/workflows/dotnet-lib-release.yml b/.github/workflows/dotnet-lib-release.yml index f767baa5..8aacddb2 100644 --- a/.github/workflows/dotnet-lib-release.yml +++ b/.github/workflows/dotnet-lib-release.yml @@ -202,6 +202,14 @@ jobs: cicd-pat: "${{ secrets.cicd-pat }}" + validate_sdk_setup: + name: Validate SDK Setup + needs: print_validate_workflow + uses: KinsonDigital/Infrastructure/.github/workflows/validate-sdk-setup.yml@v13.5.0 + with: + repo-name: "${{ inputs.project-name }}" + + nuget_pkg_does_not_exist: name: Validate NuGet Package Does Not Exist needs: validate_version @@ -263,9 +271,15 @@ jobs: name: Perform ${{ inputs.release-type }} Release runs-on: ubuntu-latest needs: [ - validate_version, build_project, run_tests, - validate_branch, validate_tag, nuget_pkg_does_not_exist, - validate_milestone_status, validate_github_release] + validate_version, + build_project, + run_tests, + validate_branch, + validate_tag, + validate_sdk_setup, + nuget_pkg_does_not_exist, + validate_milestone_status, + validate_github_release] steps: - name: Checkout Repository uses: actions/checkout@v4 From 3405b4257b0e18f207a89338005c6916c73688e7 Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 16:16:28 +0000 Subject: [PATCH 13/20] refactor: clean and reformat code to project coding standards --- .github/workflows/validate-sdk-setup.yml | 2 +- cicd/core/Services/DenoVersionService.ts | 10 ++++---- cicd/core/Services/VersionServiceBase.ts | 8 +++--- cicd/core/Utils.ts | 4 +-- cicd/scripts/runners/PrepareReleaseRunner.ts | 2 +- .../scripts/runners/ValidateSDKSetupRunner.ts | 25 ++++++++----------- cicd/scripts/validate-sdk-setup.ts | 2 +- 7 files changed, 24 insertions(+), 29 deletions(-) diff --git a/.github/workflows/validate-sdk-setup.yml b/.github/workflows/validate-sdk-setup.yml index 75935237..a7138082 100644 --- a/.github/workflows/validate-sdk-setup.yml +++ b/.github/workflows/validate-sdk-setup.yml @@ -30,7 +30,7 @@ jobs: name: Validate SDK Setup runs-on: ubuntu-latest steps: - - name: Validate + - name: Validate Workflow Inputs run: | $repoName = "${{ inputs.repo-name }}"; diff --git a/cicd/core/Services/DenoVersionService.ts b/cicd/core/Services/DenoVersionService.ts index c687ad75..328ca5b1 100644 --- a/cicd/core/Services/DenoVersionService.ts +++ b/cicd/core/Services/DenoVersionService.ts @@ -38,10 +38,10 @@ export class DenoVersionService extends VersionServiceBase { Utils.printAsGitHubError(errorMsg); Deno.exit(1); } - + let denoConfigFileData = await this.getFileData(releaseType); const denoConfigFileName = await this.getVersionFilePath(); - + if (this.fileContainsVersionSchema(denoConfigFileData)) { if (this.versionAlreadyUpdated(denoConfigFileData, version)) { let errorMsg = `The version '${version}' is already set for the version key in the file '${denoConfigFileName}'.`; @@ -52,7 +52,7 @@ export class DenoVersionService extends VersionServiceBase { // Build the replacement version key and value const newVersionKeyAndValue = `"version": "${version}"`; - + // Since the version already exists and it is different than what the new version is, //replace the version key and value with the new key and value denoConfigFileData = denoConfigFileData.replace(this.versionKeyRegex, newVersionKeyAndValue); @@ -91,7 +91,7 @@ export class DenoVersionService extends VersionServiceBase { } const versionSection = jsonKeyAndValue.split(":")[1] - .replaceAll("\"", "").trim().toLowerCase(); + .replaceAll('"', "").trim().toLowerCase(); return versionSection === version; } @@ -106,7 +106,7 @@ export class DenoVersionService extends VersionServiceBase { const jsonObj = JSON.parse(fileData); const indent = 4; const newLineChars = isWindows ? "\r\n" : "\n"; - + // Add a prop and value to the json object jsonObj["version"] = version; diff --git a/cicd/core/Services/VersionServiceBase.ts b/cicd/core/Services/VersionServiceBase.ts index 86c61580..16c902e8 100644 --- a/cicd/core/Services/VersionServiceBase.ts +++ b/cicd/core/Services/VersionServiceBase.ts @@ -53,7 +53,7 @@ export abstract class VersionServiceBase { * @param fileData The file data to check. */ public abstract fileContainsVersionSchema(fileData: string): boolean; - + /** * Checks if the given {@link fileData} already has the given {@link version}. * @param fileData The file data to check. @@ -132,7 +132,7 @@ export abstract class VersionServiceBase { // If the branch name has not been set yet, cache it if (Utils.isNothing(this.branchName)) { let branchVarName = ""; - + switch (releaseType) { case ReleaseType.preview: branchVarName = VersionServiceBase.PREV_PREP_RELEASE_HEAD_BRANCH; @@ -144,7 +144,7 @@ export abstract class VersionServiceBase { Utils.printAsGitHubError(`Unknown release type '${releaseType}'.`); Deno.exit(1); } - + const branchName = await this.githubVarService.getValue(branchVarName); this.branchName = branchName; } @@ -184,6 +184,6 @@ export abstract class VersionServiceBase { VersionServiceBase.PREP_PROJ_RELATIVE_FILE_PATH, VersionServiceBase.PREV_PREP_RELEASE_HEAD_BRANCH, VersionServiceBase.PROD_PREP_RELEASE_HEAD_BRANCH, - ] + ]; } } diff --git a/cicd/core/Utils.ts b/cicd/core/Utils.ts index 7c39ddd5..0c73a300 100644 --- a/cicd/core/Utils.ts +++ b/cicd/core/Utils.ts @@ -308,9 +308,7 @@ export class Utils { public static getCSProjTargetFrameworkVersion(csProjFileData: string): string { const tagMatches = csProjFileData.match(this.targetFrameworkRegex); - const targetFrameworkTags = tagMatches === null || tagMatches.length === 0 - ? [] - : [...tagMatches]; + const targetFrameworkTags = tagMatches === null || tagMatches.length === 0 ? [] : [...tagMatches]; if (targetFrameworkTags.length === 0) { throw new Error("Could not find any target framework XML tags in the given csproj file data."); diff --git a/cicd/scripts/runners/PrepareReleaseRunner.ts b/cicd/scripts/runners/PrepareReleaseRunner.ts index 2ba91d9e..64c5844e 100644 --- a/cicd/scripts/runners/PrepareReleaseRunner.ts +++ b/cicd/scripts/runners/PrepareReleaseRunner.ts @@ -131,7 +131,7 @@ export class PrepareReleaseRunner extends ScriptRunner { Deno.exit(1); } - console.log(`Adding pull request '${newPr.number}' to project '${orgProjectName}'.`) + console.log(`Adding pull request '${newPr.number}' to project '${orgProjectName}'.`); await projectClient.addPullRequestToProject(newPr.number, orgProjectName); // Update the pull request by setting the default reviewer, org project, labels and milestone diff --git a/cicd/scripts/runners/ValidateSDKSetupRunner.ts b/cicd/scripts/runners/ValidateSDKSetupRunner.ts index b2583e21..936f3b67 100644 --- a/cicd/scripts/runners/ValidateSDKSetupRunner.ts +++ b/cicd/scripts/runners/ValidateSDKSetupRunner.ts @@ -37,9 +37,7 @@ export class ValidateSDKSetupRunner extends ScriptRunner { throw new Error("The NET_SDK_VERSION variable is not defined."); } - dotnetSDKVersion = dotnetSDKVersion.startsWith("v") - ? dotnetSDKVersion.substring(1) - : dotnetSDKVersion; + dotnetSDKVersion = dotnetSDKVersion.startsWith("v") ? dotnetSDKVersion.substring(1) : dotnetSDKVersion; if (!Utils.isValidDotnetSDKVersion(dotnetSDKVersion)) { Utils.printAsGitHubError(`The NET_SDK_VERSION variable is not a valid dotnet version: ${dotnetSDKVersion}`); @@ -51,7 +49,7 @@ export class ValidateSDKSetupRunner extends ScriptRunner { const filesWithoutTargetFramework: string[] = []; const nonMatchingVersions: [string, string][] = []; - + for (const csProjFile of csProFiles) { const fileData = Deno.readTextFileSync(csProjFile); @@ -64,16 +62,16 @@ export class ValidateSDKSetupRunner extends ScriptRunner { } catch (error) { nonMatchingVersions.push([csProjFile, error.message]); } - + const versionsMatch = this.versionsMatch(dotnetSDKVersion, targetFrameworkVersion); - + if (versionsMatch) { continue; } - + const errorMsg = `The target framework version in the csproj file '${csProjFile}' does not match the repo` + - ` variable NET_SDK_VERSION.`; - nonMatchingVersions.push([csProjFile, errorMsg]) + ` variable NET_SDK_VERSION.`; + nonMatchingVersions.push([csProjFile, errorMsg]); } else { filesWithoutTargetFramework.push(csProjFile); } @@ -81,12 +79,12 @@ export class ValidateSDKSetupRunner extends ScriptRunner { // If there are any issues with any of the files, print them out. if (filesWithoutTargetFramework.length > 0 || nonMatchingVersions.length > 0) { - filesWithoutTargetFramework.forEach(fileWithout => { + filesWithoutTargetFramework.forEach((fileWithout) => { Utils.printAsGitHubError(`The file '${fileWithout}' does not have a target framework defined.`); }); - nonMatchingVersions.forEach(nonMatchingVersion => { - const errorMsg = `The file '${nonMatchingVersion[0]}' has a target framework version that does not ` + + nonMatchingVersions.forEach((nonMatchingVersion) => { + const errorMsg = `The file '${nonMatchingVersion[0]}' has a target framework version that does not ` + `match the NET_SDK_VERSION variable.\n${nonMatchingVersion[1]}`; Utils.printAsGitHubError(errorMsg); }); @@ -104,8 +102,7 @@ export class ValidateSDKSetupRunner extends ScriptRunner { // Validate that the repo exists const repoExists = await this.repoClient.exists(); - if (!repoExists) - { + if (!repoExists) { throw new Error(`The repo ${repoOwner}/${repoName} does not exist.`); } diff --git a/cicd/scripts/validate-sdk-setup.ts b/cicd/scripts/validate-sdk-setup.ts index 9cd0d522..44bc052f 100644 --- a/cicd/scripts/validate-sdk-setup.ts +++ b/cicd/scripts/validate-sdk-setup.ts @@ -9,7 +9,7 @@ const validateSDKSetupExecutor = async () => { console.error(error); Deno.exit(1); } -} +}; validateSDKSetupExecutor(); From 533bbb465b57c6fb2b48a6275bf4f2e102281f0a Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 16:20:44 +0000 Subject: [PATCH 14/20] ci: update workflows to use preview branch --- .github/workflows/add-new-item-to-project.yml | 2 +- .github/workflows/build-status-check.yml | 2 +- .github/workflows/lint-status-check.yml | 2 +- .github/workflows/workflow-version-status-check.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/add-new-item-to-project.yml b/.github/workflows/add-new-item-to-project.yml index e93ac771..4f69b585 100644 --- a/.github/workflows/add-new-item-to-project.yml +++ b/.github/workflows/add-new-item-to-project.yml @@ -11,7 +11,7 @@ on: types: opened pull_request: types: opened - branches: main + branches: [main, preview] jobs: diff --git a/.github/workflows/build-status-check.yml b/.github/workflows/build-status-check.yml index 4ceef804..34a72086 100644 --- a/.github/workflows/build-status-check.yml +++ b/.github/workflows/build-status-check.yml @@ -9,7 +9,7 @@ defaults: on: pull_request_target: - branches: main + branches: [main, preview] jobs: diff --git a/.github/workflows/lint-status-check.yml b/.github/workflows/lint-status-check.yml index 2bc924a3..78a75874 100644 --- a/.github/workflows/lint-status-check.yml +++ b/.github/workflows/lint-status-check.yml @@ -8,7 +8,7 @@ defaults: on: pull_request: - branches: main + branches: [main, preview] jobs: diff --git a/.github/workflows/workflow-version-status-check.yml b/.github/workflows/workflow-version-status-check.yml index 5cdeeca0..9d5e6bf3 100644 --- a/.github/workflows/workflow-version-status-check.yml +++ b/.github/workflows/workflow-version-status-check.yml @@ -8,7 +8,7 @@ defaults: on: pull_request: - branches: main + branches: [main, preview] jobs: From d7578ba8d9bb4af78f19e930f146d92ecbcc45ce Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 16:25:10 +0000 Subject: [PATCH 15/20] chore: improve version regex --- cicd/core/Utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cicd/core/Utils.ts b/cicd/core/Utils.ts index 0c73a300..1ff74f2f 100644 --- a/cicd/core/Utils.ts +++ b/cicd/core/Utils.ts @@ -7,7 +7,7 @@ import { IssueModel, LabelModel, ProjectModel, PullRequestModel, UserModel } fro */ export class Utils { private static readonly prodVersionRegex = /^v([1-9]\d*|0)\.([1-9]\d*|0)\.([1-9]\d*|0)$/; - private static readonly prevVersionRegex = /^v([1-9]\d*|0)\.([1-9]\d*|0)\.([1-9]\d*|0)(-preview\.([1-9]\d*))?$/; + private static readonly prevVersionRegex = /^v([1-9]\d*|0)\.([1-9]\d*|0)\.([1-9]\d*|0)-preview\.([1-9]\d*|0)$/; private static readonly dotnetSDKVersionRegex = /([1-9]\d*|0)\.([1-9]\d*|0)\.([1-9]\d*|0)/gm; private static readonly csprojTargetFrameworkVersionRegex = /net([1-9]\d*|0)(\.([1-9]\d*|0)|)(\.([1-9]\d*|0)|)/gm; private static readonly targetFrameworkRegex = /\s*net.+\s*<\/TargetFramework\s*>/gm; From 796b1bdc7f323d7771f67b7012a8e06c08549470 Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 16:25:18 +0000 Subject: [PATCH 16/20] ci: remove testing workflow --- .github/workflows/prepare-release-test.yml | 83 ---------------------- 1 file changed, 83 deletions(-) delete mode 100644 .github/workflows/prepare-release-test.yml diff --git a/.github/workflows/prepare-release-test.yml b/.github/workflows/prepare-release-test.yml deleted file mode 100644 index c2ca3cc1..00000000 --- a/.github/workflows/prepare-release-test.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: 🚁Prepare Release Test -run-name: 🚁Prepare ${{ inputs.release-type }} Release Test (${{ inputs.release-version }}) - - -defaults: - run: - shell: pwsh - - -on: - workflow_dispatch: - inputs: - release-type: - description: The type of release. Choose 'Preview' or 'Production'. - required: true - type: choice - options: [Preview, Production] - release-version: - required: true - description: The version of the release to prepare. - type: string - - -jobs: - print_validate_workflow: - name: Print & Validate Prepare Release Workflow - runs-on: ubuntu-latest - steps: - - name: Print Environment Variables - run: Get-ChildItem -Path Env:* | Sort-Object Name - - - name: Validate Workflow Inputs - run: | - $releaseType = "${{ inputs.release-type }}".ToLower(); - - if ("${{ vars.PROJECT_NAME }}".Trim() -eq "") { - Write-Host "::error::The project name input cannot be empty."; - exit 1; - } - - - if ($releaseType -eq "") { - Write-Host "::error::The release type input cannot be empty."; - exit 1; - } - - - if ($releaseType -ne 'preview' -and $releaseType -ne 'production') { - Write-Host "::error::The release type input must be either 'Preview' or 'Production'."; - exit 1; - } - - $releaseVersion = "${{ inputs.release-version }}".Trim().ToLower(); - - if ($releaseVersion -eq "") { - Write-Host "::error::The 'release-version' workflow input cannot be empty."; - exit 1; - } - - - $prodVersionRegex = "v[0-9]+\.[0-9]+\.[0-9]+"; - $prevVersionRegex = "v[0-9]+\.[0-9]+\.[0-9]+-preview\.[0-9]+"; - - # Verify that the version has valid syntax - if (($releaseVersion -match $prodVersionRegex) -or ($releaseVersion -match $prevVersionRegex)) { - Write-Host "::notice::The 'release-version' workflow input is valid."; - } else { - $versionSyntax = $releaseType == "production" ? "v#.#.#" : "v#.#.#-preview.#"; - Write-Host "::error::The 'release-version' workflow input is not valid. Expected format: '$versionSyntax"; - exit 1; - } - - - prepare_release: - name: Prepare ${{ inputs.release-type }} Release Of ${{ vars.PROJECT_NAME }} - needs: print_validate_workflow - uses: KinsonDigital/Infrastructure/.github/workflows/prepare-release.yml@v13.5.0 - with: - project-name: "${{ vars.PROJECT_NAME }}" - release-type: "${{ inputs.release-type }}" - release-version: "${{ inputs.release-version }}" - secrets: - cicd-pat: ${{ secrets.CICD_TOKEN }} From 6bd15e0f07e2fdea09a6dd06f1581135c23adcbf Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 16:25:41 +0000 Subject: [PATCH 17/20] ci: improve version regex in workflow validation job --- .github/workflows/prepare-release.yml | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 94bfc610..9e13238f 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -57,19 +57,15 @@ jobs: } - $releaseVersion = "${{ inputs.release-version }}".Trim().ToLower(); - $releaseVersion = $releaseVersion.StartsWith("v") ? $releaseVersion : "v$releaseVersion"; - - if ($releaseType -eq "production") { - if ($releaseVersion -notmatch "v[0-9]+\.[0-9]+\.[0-9]+") { - Write-Host "::error::The production release version input is invalid. Expected version format: 'v#.#.#'"; - exit 1; - } + $versionRegex = "^v([1-9]\d*|0)\.([1-9]\d*|0)\.([1-9]\d*|0)(-preview\.([1-9]\d*|0))?$"; + + # Verify that the version has valid syntax + if (($releaseVersion -match $versionRegex)) { + Write-Host "::notice::The 'release-version' workflow input is valid."; } else { - if ($releaseVersion -notmatch "v[0-9]+\.[0-9]+\.[0-9]+-preview\.[0-9]+") { - Write-Host "::error::The preview release version input is invalid. Expected version format: 'v#.#.#-preview.#'"; - exit 1; - } + $versionSyntax = $releaseType == "production" ? "v#.#.#" : "v#.#.#-preview.#"; + Write-Host "::error::The 'release-version' workflow input is not valid. Expected format: '$versionSyntax"; + exit 1; } From 6e3911fcde2ce9e72fde9e7bf326da2c15357ad4 Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 16:30:57 +0000 Subject: [PATCH 18/20] ci: setup workflow version status check to only run for release branches --- .github/workflows/workflow-version-status-check.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/workflow-version-status-check.yml b/.github/workflows/workflow-version-status-check.yml index 9d5e6bf3..07b2128e 100644 --- a/.github/workflows/workflow-version-status-check.yml +++ b/.github/workflows/workflow-version-status-check.yml @@ -15,6 +15,7 @@ jobs: workflow_version_status_check: name: Workflow Version Status Check runs-on: ubuntu-latest + if: github.head_ref == ${{ vars.PREV_PREP_RELEASE_HEAD_BRANCH }} || github.head_ref == ${{ vars.PROD_PREP_RELEASE_HEAD_BRANCH }} steps: - name: Checkout uses: actions/checkout@v4 From 1e96268f0ab659f4a5cbd27f3d28236eed1c0552 Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 16:35:57 +0000 Subject: [PATCH 19/20] config: add task to deno config file --- deno.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deno.json b/deno.json index 62b1d446..f007ee5e 100644 --- a/deno.json +++ b/deno.json @@ -4,7 +4,8 @@ "clear": "deno run -A ./.github/internal-cicd/deno-tasks/clear-screen.ts", "build": "deno task clear && deno run -A ./.github/internal-cicd/scripts/deno-check.ts", "lint": "deno task clear && deno lint", - "format": "deno task clear && deno fmt" + "format": "deno task clear && deno fmt", + "reload-cache": "deno task clear && deno cache --lock=deno.lock --lock-write \"./cicd/scripts/mod.ts\"" }, "lint": { "include": [ From 1889f3d29db0cb8e5440eedeedcd70807a99294c Mon Sep 17 00:00:00 2001 From: Calvin Wilkinson Date: Mon, 18 Dec 2023 16:38:58 +0000 Subject: [PATCH 20/20] force status checks