Skip to content

Commit

Permalink
🚧Create release workflow (#240)
Browse files Browse the repository at this point in the history
* Start work for issue #201

* config: replace deno check with deno check command

* refactor: update code to meet coding standards

* ci: remove unnecessary env vars

* ci: create scripts for release workflow

* config: add item to gitignore for script output during dev testing

* ci: improve build status check workflow

* config: improve deno tasks

* ci: create release workflow

* ci: update all setup deno actions to version 2
  • Loading branch information
CalvinWilkinson committed Oct 10, 2024
1 parent ca3e15f commit 06c8b7d
Show file tree
Hide file tree
Showing 36 changed files with 543 additions and 316 deletions.
96 changes: 0 additions & 96 deletions .github/internal-cicd/scripts/deno-check.ts

This file was deleted.

33 changes: 33 additions & 0 deletions .github/internal-cicd/scripts/get-validate-version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import getEnvVar from "../../../cicd/core/GetEnvVar.ts";
import { Utils } from "../../../cicd/core/Utils.ts";
import DenoConfig from "../../../deno.json" with { type: "json" };

const scriptFileName = new URL(import.meta.url).pathname.split("/").pop();

if (Utils.isNothing(DenoConfig.version)) {
Utils.printAsGitHubError(`The Deno version is not defined in the deno.json file.\n${scriptFileName}`);
Deno.exit(1);
}

const githubOutputFilePath = getEnvVar("GITHUB_OUTPUT", scriptFileName);

const version = (DenoConfig.version.startsWith("v") ? DenoConfig.version : `v${DenoConfig.version}`).trim().toLocaleLowerCase();

const versionRegex = /^v([1-9]\d*|0)\.([1-9]\d*|0)\.([1-9]\d*|0)(-preview\.([1-9]\d*))?$/gm;

if (!versionRegex.test(version)) {
Utils.printAsGitHubError(`The version '${version}' is not valid.\n\t\n${scriptFileName}`);
Deno.exit(1);
}

try {
Deno.writeTextFileSync(githubOutputFilePath, `version=${version}\n`, { append: true });
} catch (error) {
if (error instanceof Error) {
Utils.printAsGitHubError(`${error.message}\n${scriptFileName}`);
} else {
Utils.printAsGitHubError(`An unknown error occurred.\n${scriptFileName}`);
}

Deno.exit(1);
}
1 change: 0 additions & 1 deletion .github/internal-cicd/scripts/update-csharp-proj.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,3 @@ const token = getEnvVar("GITHUB_TOKEN", scriptFileName);
const service = new CSharpVersionService("KinsonDigital", "Infrastructure", token);

await service.updateVersion(version, ReleaseType.preview);

21 changes: 11 additions & 10 deletions .github/internal-cicd/scripts/update-workflow-versions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import {
TagClient, RepoClient, Directory, Input
} from "../../../deps.ts";
import { Directory, Input, RepoClient, TagClient } from "../../../deps.ts";
import chalk from "../../../deps.ts";
import { File } from "../../../cicd/core/File.ts";
import { Utils } from "../../../cicd/core/Utils.ts";
Expand Down Expand Up @@ -34,7 +32,7 @@ const newVersion = await Input.prompt({
value = value.trim().toLowerCase();

return value.startsWith("v") ? value : `v${value}`;
}
},
});

const ownerName = "KinsonDigital";
Expand All @@ -58,15 +56,15 @@ const updateMsgs: string[] = [];
let noFilesUpdated = true;

// Search for workflow references with a version that has not been updated
yamlFiles.forEach(yamlFile => {
yamlFiles.forEach((yamlFile) => {
let fileContent = File.LoadFile(yamlFile);

const possibleUpdates = fileContent.match(reusableWorkflowRegex)?.map((w) => w) ?? [];

let fileUpdated = false;

// Check each reusable workflow reference version
possibleUpdates.forEach(oldRef => {
// Check each reusable workflow reference version
possibleUpdates.forEach((oldRef) => {
const refPathSection = oldRef.split("uses:")[1].trim().split("@")[0];
const workflowRefVersion = oldRef.split("@")[1];

Expand All @@ -79,7 +77,8 @@ yamlFiles.forEach(yamlFile => {
// Update the reusable workflow reference version
fileContent = fileContent.replaceAll(oldRef, newRef);

const noticeMsg = `Updated reusable workflow reference '${refPathSection}' from version '${workflowRefVersion}' to '${newVersion}'.`;
const noticeMsg =
`Updated reusable workflow reference '${refPathSection}' from version '${workflowRefVersion}' to '${newVersion}'.`;
updateMsgs.push(noticeMsg);
}
});
Expand All @@ -96,7 +95,7 @@ if (noFilesUpdated) {
console.log(chalk.cyan("No files needed updating."));
} else {
updateMsgs.sort();
updateMsgs.forEach(updateMsg => {
updateMsgs.forEach((updateMsg) => {
console.log(chalk.cyan(updateMsg));
});
}
Expand All @@ -113,4 +112,6 @@ const scriptVersionVar = (await repoClient.getVariables()).find((v) => v.name ==

await repoClient.updateVariable(repoVarName, newVersion);

console.log(chalk.cyan(`Updated repository variable '${repoVarName}' from version '${scriptVersionVar?.value}' to '${newVersion}'.`));
console.log(
chalk.cyan(`Updated repository variable '${repoVarName}' from version '${scriptVersionVar?.value}' to '${newVersion}'.`),
);
101 changes: 1 addition & 100 deletions .github/internal-cicd/scripts/workflow-version-status-check.ts
Original file line number Diff line number Diff line change
@@ -1,100 +1 @@
import { walkSync } from "@std/fs/walk";
import { exists } from "@std/fs/exists";
import { basename } from "@std/path/basename";
import { TagClient } from "../../../deps.ts";
import { Utils } from "../../../cicd/core/Utils.ts";
import getEnvVar from "../../../cicd/core/GetEnvVar.ts";
import { validateOrgExists, validateRepoExists } from "../../../cicd/core/Validators.ts";

const scriptFileName = new URL(import.meta.url).pathname.split("/").pop();

const ownerName = getEnvVar("OWNER_NAME", scriptFileName);
const repoName = getEnvVar("REPO_NAME", scriptFileName);
let baseDirPath = getEnvVar("BASE_DIR_PATH", scriptFileName);
baseDirPath = Utils.normalizePath(baseDirPath);
const token = getEnvVar("GITHUB_TOKEN", scriptFileName);

await validateOrgExists(scriptFileName);
await validateRepoExists(scriptFileName);

if (!exists(baseDirPath)) {
Utils.printAsGitHubError(`Directory '${baseDirPath}' does not exist.`);
Deno.exit(1);
}

const yamlFiles = [...walkSync(baseDirPath, {
includeDirs: false,
includeFiles: true,
exts: [".yaml", ".yml"],
})].map((e) => e.path);

const tagClient: TagClient = new TagClient(ownerName, repoName, token);

const existingReleaseTags = (await tagClient.getAllTags()).map((t) => t.name);

const workflowsToUpdate: WorkflowToUpdate[] = [];

const reusableWorkflowRegex = /uses: .+.(yml|yaml)@v([1-9]\d*|0)\.([1-9]\d*|0)\.([1-9]\d*|0)(-preview\.([1-9]\d*))?/gm;

type WorkflowToUpdate = {
/**
* The file path to the workflow.
*/
filePath: string;

/**
* The reusable workflow references that need to be updated.
*/
workflowRefs: string[];
};

// Search for workflow references with a version that has not been updated
yamlFiles.forEach(yamlFile => {
const workflowToUpdate: WorkflowToUpdate = {
filePath: yamlFile,
workflowRefs: []
};

const fileContent = Deno.readTextFileSync(yamlFile);

const possibleUpdates = fileContent.match(reusableWorkflowRegex)?.map((w) => w) ?? [];

// Check each reusable workflow reference version
possibleUpdates.forEach(possibleUpdate => {
const fullRef = possibleUpdate.split("uses:")[1].trim();
const workflowRefVersion = possibleUpdate.split("@")[1];

// If the workflow version has not been updated
if (existingReleaseTags.includes(workflowRefVersion)) {
workflowToUpdate.workflowRefs.push(fullRef);
}
});

if (workflowToUpdate.workflowRefs.length > 0) {
workflowsToUpdate.push(workflowToUpdate);
}
});

// If there are no workflows to update, then exit
if (workflowsToUpdate.length === 0) {
Utils.printAsGitHubNotice("No workflows to update.");
Deno.exit(0);
}

const errorMsgs: string[] = [];

// Print out all of the workflows that need to be updated as an error
workflowsToUpdate.forEach(workflowToUpdate => {
const filePath = basename(workflowToUpdate.filePath);

const workflowErrors: string[] = workflowToUpdate.workflowRefs.map((workflowRef) => {
return `Workflow reference '${workflowRef}' in file '${filePath}' needs to be updated.`;
});

errorMsgs.push(...workflowErrors);
});

if (errorMsgs.length > 0) {
Utils.printAsGitHubErrors(errorMsgs);
Deno.exit(1);
}
import "../../../cicd/scripts/check-workflow-versions.ts";
2 changes: 1 addition & 1 deletion .github/workflows/add-item-to-project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
}
- name: Set Up Deno
uses: denoland/setup-deno@v1
uses: denoland/setup-deno@v2
with:
deno-version: ${{ vars.DENO_VERSION }}

Expand Down
9 changes: 4 additions & 5 deletions .github/workflows/build-status-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ jobs:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.ref }}

- name: Setup Deno
uses: denoland/setup-deno@v1
- name: Setup Deno (${{ vars.DENO_VERSION }})
uses: denoland/setup-deno@v2
with:
deno-version: ${{ vars.DENO_VERSION }}

- name: Run Build
run: |
deno run --allow-read --allow-run --allow-sys "./.github/internal-cicd/scripts/deno-check.ts";
- name: Run Check
run: deno check ./**/*.ts;
10 changes: 2 additions & 8 deletions .github/workflows/dotnet-lib-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Set Up Deno
uses: denoland/setup-deno@v1
uses: denoland/setup-deno@v2
with:
deno-version: ${{ vars.DENO_VERSION }}

Expand Down Expand Up @@ -138,8 +138,6 @@ jobs:
id: tag-check
continue-on-error: true
env:
OWNER_NAME: "${{ vars.ORGANIZATION_NAME }}"
REPO_NAME: "${{ inputs.project-name }}"
RELEASE_TYPE: "${{ inputs.release-type }}"
TAG_NAME: "${{ needs.validate_version.outputs.version }}"
GITHUB_TOKEN: "${{ secrets.cicd-pat }}"
Expand Down Expand Up @@ -186,8 +184,6 @@ jobs:
- name: Validate Milestone
id: milestone-check
env:
OWNER_NAME: "${{ vars.ORGANIZATION_NAME }}"
REPO_NAME: "${{ inputs.project-name }}"
MILESTONE_TITLE: "${{ needs.validate_version.outputs.version }}"
GITHUB_TOKEN: "${{ secrets.cicd-pat }}"
continue-on-error: true
Expand All @@ -200,8 +196,6 @@ jobs:
id: github-release-check
continue-on-error: true
env:
OWNER_NAME: "${{ vars.ORGANIZATION_NAME }}"
REPO_NAME: "${{ inputs.project-name }}"
TAG_NAME: "${{ needs.validate_version.outputs.version }}"
GITHUB_TOKEN: "${{ secrets.cicd-pat }}"
run: |
Expand Down Expand Up @@ -304,7 +298,7 @@ jobs:
uses: NuGet/setup-nuget@v1

- name: Set Up Deno
uses: denoland/setup-deno@v1
uses: denoland/setup-deno@v2
with:
deno-version: ${{ vars.DENO_VERSION }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/initial-manual-sync.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
- name: Set Up Deno
if: ${{ steps.skip-checking.outputs.skip == 'false' }}
uses: denoland/setup-deno@v1
uses: denoland/setup-deno@v2
with:
deno-version: ${{ vars.DENO_VERSION }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint-status-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
uses: actions/checkout@v4

- name: Set Up Deno
uses: denoland/setup-deno@v1
uses: denoland/setup-deno@v2
with:
deno-version: ${{ vars.DENO_VERSION }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nuget-package-does-not-exist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Set Up Deno
uses: denoland/setup-deno@v1
uses: denoland/setup-deno@v2
with:
deno-version: ${{ vars.DENO_VERSION }}

Expand Down
Loading

0 comments on commit 06c8b7d

Please sign in to comment.