Skip to content

Restore auto-release for velaptor docs #1165

@CalvinWilkinson

Description

@CalvinWilkinson

Complete The Items Below

  • A priority label has been added to this issue.

Description

Previously, deno scripts and workflows were removed that enabled the release workflow to execute a VelaptorDocs release once a Velaptor release was finished. Restore this functionality. The idea here is to take advantage of the new docs release/update process.

Before, the docs website did not take advantage of the Next release concept. Now it does. Next always represents the latest and greatest, along with WIP docs for an upcoming WIP Velaptor release. This means that instead of waiting for a Velaptor release to complete before doing a docs release, we can merge all required Velaptor PRs and simply not do a Velaptor release until the docs are complete.

This means we can develop the docs for the upcoming release alongside the development of Velaptor. Once we are ready to do a Velaptor release, all we need to do is make sure the docs are updated before we run the Velaptor release. This way, the Velaptor release will trigger the release of the Velaptor docs website, and everything will be released at the same time.

In the scripts below, they use a tuple in string format to pass workflow info to the trigger-api-docs-release.ts script. This script would then parse the tuple info and convert it to JSON for the GitHub API request body.

To exeucte the workflow externally, use the following command using the GitHub CLI

gh workflow run test-workflow.yml -R "KinsonDigital/VelaptorDocs" --ref "test-branch" --field "api-version=v1.2.3-preview.4" --field "executed-externally=true"
  1. Create a script that compiles all that is needed to execute the VelaptorDocs workflow. The script should be minimal and improved.
  2. Update the release workflow to take in an input to trigger the docs release workflow.

Use the old scripts below to create a new script that combines them.

trigger-api-docs-release.ts

import { WorkflowClient } from "clients/WorkflowClient.ts";
import { Confirm } from "https://deno.land/x/cliffy@v1.0.0-rc.4/prompt/confirm.ts";

// Check that the required number of arguments were provided
if (Deno.args.length != 5) {
    let errorMsg = `The required number of arguments is 5 but only '${Deno.args.length}' was provided`;
    errorMsg += "\nThe required arguments are as follows:";
    errorMsg += "\n1. Repository Name: The name of the repository where the workflow is located.";
    errorMsg += "\n2. Branch Name: The name of the branch where the workflow is located.";
    errorMsg += "\n3. Workflow Name: The name of the workflow to execute.";
    errorMsg += "\n4. Workflow Inputs: The comma-delimited list of inputs to pass to the workflow.";
    errorMsg += "\n\tNOTE: Syntax is a comma-delimited list of key value pairs wrapped in square brackets.";
    errorMsg += "\n\tExample: '[item1,value1]|[item2, value1]'";
    errorMsg += "\n5. GitHub PAT: The GitHub Personal Access Token to use for authentication.";
    Deno.exit(1);
}

const doNotExecuteRelease = !(await Confirm.prompt({
    message: "Are you sure you want to trigger an API docs release?",
    validate: (value) => {
        return value.length === 1 && value[0].toUpperCase() === "Y" || value[0].toUpperCase() === "N";
    },
}));

if (doNotExecuteRelease) {
    console.log("API docs release cancelled.");
    Deno.exit();
}

console.log("Executing API docs release...");

const args = Deno.args.map((arg) => arg.trim());
const repoName = args[0].trim();
const branchName = args[1].trim();
const workflowFileName = args[2].trim();
const rawWorkflowInputList = args[3].trim();
const token = args[4].trim();

// First get a list of the workflow tuples(key value pairs)
const tuples: string[] = rawWorkflowInputList.indexOf("|") != -1
    ? rawWorkflowInputList.split("|").map((input) => input.trim().replace("[", "").replace("]", ""))
    : [rawWorkflowInputList.trim().replace("[", "").replace("]", "")];

const workflowInputs: [string, string][] = [];

for (const tuple of tuples) {
    const [key, value] = tuple.split(",").map((input) => input.trim());
    workflowInputs.push([key, value]);
}

const containsPAT = (value: string): boolean => {
    const fineGrainedTokenPrefix = "github_pat_";
    const classicTokenPrefix = "ghp_";

    return value.startsWith(fineGrainedTokenPrefix) || value.startsWith(classicTokenPrefix);
}

const printGitHubError = (errorMsg: string): void => {
    console.log(`::error::${errorMsg}`);
};

const toOrdinal = (number: number): string => {
    const suffixes = ["th", "st", "nd", "rd"];
    const value = Math.abs(number) % 100;
    const suffix = suffixes[(value - 20) % 10] || suffixes[value] || suffixes[0];

    return `${number}${suffix}`;
};

const argNames = ["Repository Name", "Branch Name", "Workflow Name", "Workflow Inputs", "GitHub PAT"];

// Print out all of the arguments as long as they don't contain a PAT
for (let i = 0; i < args.length; i++) {
    const arg = args[i];
    
    if (i === args.length - 1) {
        console.log(`${argNames[i]}: ***`);

        if (!containsPAT(token)) {
            const errorMsg = `The ${toOrdinal(i + 1)} argument (GitHub PAT) is not a valid GitHub personal access token.`;
            printGitHubError(errorMsg);
            Deno.exit(1);
        }
    } else {
        const isInvalid = containsPAT(arg);
        console.log(`${argNames[i]}: ${isInvalid ? "***" : args[i]}`);

        if (isInvalid) {
            const errorMsg = `A GitHub PAT was found in the ${toOrdinal(i + 1)} argument. This is not allowed.`;
            printGitHubError(errorMsg);
            
            Deno.exit(1);
        }
    }
}

const client = new WorkflowClient(token);
await client.executeWorkflow(repoName, branchName, workflowFileName, workflowInputs);

Workflow Client Script

import { Guard } from "../core/Guard.ts";
import { Utils } from "../core/Utils.ts";
import { GitHubHttpStatusCodes, WorkflowEvent, WorkflowRunStatus } from "../core/Enums.ts";
import { GitHubClient } from "../core/GitHubClient.ts";
import { WorkflowRunModel } from "../core/Models/WorkflowRunModel.ts";
import { WorkflowRunsModel } from "../core/Models/WorkflowRunsModel.ts";
import { AnyBranch } from "../core/Types.ts";
import { GithubResponse } from "./GithubResponse.ts";

/**
 * Provides a client for interacting with workflow runs.
 */
export class WorkflowClient extends GitHubClient {
	private readonly AnyBranch: AnyBranch = null;

	/**
	 * Initializes a new instance of the {@link WorkflowClient} class.
	 * @param token The GitHub token to use for authentication.
	 * @remarks If no token is provided, then the client will not be authenticated.
	 */
	constructor(token?: string) {
		super(token);
	}

	/**
	 * Gets all workflow runs for a repository that matches the given {@link repoName} for the given {@link branch},
	 * that was triggered by the given {@link event}, and has the given {@link status}.
	 * @param repoName The name of the repository.
	 * @param branch The branch that contains the workflow runs.
	 * @param event The event that triggered the workflow runs.
	 * @param status The status of the workflow runs.
	 * @param page The page of results to return.
	 * @param qtyPerPage The total to return per {@link page}.
	 * @returns The workflow runs.
	 * @remarks Does not require authentication if the repository is public.
	 * The {@link page} value must be greater than 0. If less than 1, the value of 1 will be used.
	 * The {@link qtyPerPage} value must be a value between 1 and 100. If less than 1, the value will
	 * be set to 1, if greater than 100, the value will be set to 100.
	 */
	public async getWorkflowRuns(
		repoName: string,
		branch: string | null | AnyBranch,
		event: WorkflowEvent,
		status: WorkflowRunStatus,
		page = 1,
		qtyPerPage = 100,
	): Promise<[WorkflowRunModel[], Response]> {
		Guard.isNullOrEmptyOrUndefined(repoName, "getWorkflowRuns", "repoName");

		repoName = repoName.trim();
		branch = branch?.trim() ?? "";
		page = Utils.clamp(page, 1, Number.MAX_SAFE_INTEGER);
		qtyPerPage = Utils.clamp(qtyPerPage, 1, 100);

		// GitHub API: https://docs.github.com/en/rest/actions/workflow-runs?apiVersion=2022-11-28#list-workflow-runs-for-a-repository
		const branchParam = Utils.isNullOrEmptyOrUndefined(branch) ? "" : `&branch=${branch}`;
		const eventParam = event === WorkflowEvent.any ? "" : `&event=${event}`;
		const statusParam = status === WorkflowRunStatus.any ? "" : `&status=${status}`;
		const queryParams = `?page=${page}&per_page=${qtyPerPage}${branchParam}${eventParam}${statusParam}`;
		const url = `${this.baseUrl}/repos/${this.organization}/${repoName}/actions/runs${queryParams}`;

		const response: Response = await this.requestGET(url);

		// If there is an error
		if (response.status != GitHubHttpStatusCodes.OK) {
			let errorMsg = `An error occurred trying to get the workflow runs for the repository '${repoName}'.`;
			errorMsg = `\n\tError: ${response.status}(${response.statusText})`;
			Utils.printAsGitHubError(errorMsg);
			Deno.exit(1);
		}

		const workflowRuns: WorkflowRunsModel = await this.getResponseData(response);

		return [workflowRuns.workflow_runs, response];
	}

	public async getAllWorkflowRuns(repoName: string): Promise<WorkflowRunModel[]> {
		Guard.isNullOrEmptyOrUndefined(repoName, "getAllWorkflowRuns", "repoName");

		return await this.getAllData<WorkflowRunModel>(async (page: number, qtyPerPage?: number) => {
			return await this.getWorkflowRuns(
				repoName,
				this.AnyBranch,
				WorkflowEvent.any,
				WorkflowRunStatus.any,
				page,
				qtyPerPage,
			);
		});
	}

	/**
	 * Gets all workflow runs for a repository that matches the given {@link repoName} and for the given {@link branch},
	 * that matches the given trigger {@link event}.
	 * @param repoName The name of the repository.
	 * @param branch The name of the branch where the workflow runs are located.
	 * @param event The event that triggered the workflow runs.
	 * @returns The workflow runs.
	 * @remarks Does not require authentication.
	 */
	public async getCompletedWorkflowRunsByBranch(
		repoName: string,
		branch: string,
		event: WorkflowEvent,
	): Promise<WorkflowRunModel[]> {
		const funcName = "getCompletedWorkflowRunsByBranch";
		Guard.isNullOrEmptyOrUndefined(repoName, funcName, "repoName");
		Guard.isNullOrEmptyOrUndefined(branch, funcName, "branch");

		repoName = repoName.trim();
		branch = branch.trim();

		const workflowRuns = await this.getAllData<WorkflowRunModel>(async (page: number, qtyPerPage?: number) => {
			return await this.getWorkflowRuns(repoName, branch, event, WorkflowRunStatus.completed, page, qtyPerPage);
		});

		return workflowRuns;
	}

	/**
	 * Gets all workflow runs for a repository that matches the given {@link repoName} and
	 * that matches the given trigger {@link event}.
	 * @param repoName The name of the repository.
	 * @param event The event that triggered the workflow runs.
	 * @returns The workflow runs.
	 * @remarks Does not require authentication.
	 */
	public async getCompletedWorkflowRuns(repoName: string, event: WorkflowEvent): Promise<WorkflowRunModel[]> {
		Guard.isNullOrEmptyOrUndefined(repoName, "getCompletedWorkflowRuns", "repoName");

		repoName = repoName.trim();

		const result = await this.getAllData<WorkflowRunModel>(async (page: number, qtyPerPage?: number) => {
			return await this.getWorkflowRuns(repoName, this.AnyBranch, event, WorkflowRunStatus.completed, page, qtyPerPage);
		});

		return result;
	}

	/**
	 * Gets all workflow runs for a repository that matches the given {@link repoName} and for the given {@link branch},
	 * that matches the given trigger {@link event}.
	 * @param repoName The name of the repository.
	 * @param branch The name of the branch where the workflow runs are located.
	 * @param event The event that triggered the workflow runs.
	 * @returns The workflow runs.
	 * @remarks Does not require authentication.
	 */
	public async getFailedWorkflowRunsByBranch(
		repoName: string,
		branch: string,
		event: WorkflowEvent,
	): Promise<WorkflowRunModel[]> {
		const funcName = "getFailedWorkflowRunsByBranch";
		Guard.isNullOrEmptyOrUndefined(repoName, funcName, "repoName");
		Guard.isNullOrEmptyOrUndefined(branch, funcName, "branch");

		repoName = repoName.trim();
		branch = branch.trim();

		const result = await this.getAllData<WorkflowRunModel>(async (page: number, qtyPerPage?: number) => {
			return await this.getWorkflowRuns(repoName, branch, event, WorkflowRunStatus.failure, page, qtyPerPage);
		});

		return result;
	}

	/**
	 * Gets all workflow runs for a repository that matches the given {@link repoName} and
	 * that matches the given trigger {@link event}.
	 * @param repoName The name of the repository.
	 * @param event The event that triggered the workflow runs.
	 * @returns The workflow runs.
	 * @remarks Does not require authentication.
	 */
	public async getFailedWorkflowRuns(repoName: string, event: WorkflowEvent): Promise<WorkflowRunModel[]> {
		Guard.isNullOrEmptyOrUndefined(repoName, "getFailedWorkflowRuns", "repoName");

		repoName = repoName.trim();

		const result = await this.getAllData<WorkflowRunModel>(async (page: number, qtyPerPage?: number) => {
			return await this.getWorkflowRuns(repoName, this.AnyBranch, event, WorkflowRunStatus.failure, page, qtyPerPage);
		});

		return result;
	}

	/**
	 * Gets all workflow runs for a repository that matches the given {@link repoName} and
	 * that matches the given trigger {@link event}.
	 * @param repoName The name of the repository.
	 * @param event The event that triggered the workflow runs.
	 * @param startDate The start date of when the workflow run was created.
	 * @param endDate The end date of when the workflow run was created.
	 * @returns The workflow runs.
	 * @remarks Does not require authentication.
	 */
	public async getWorkflowRunsBetweenDates(repoName: string, startDate: Date, endDate: Date): Promise<WorkflowRunModel[]> {
		Guard.isNullOrEmptyOrUndefined(repoName, "getWorkflowRunsBetweenDates", "repoName");

		repoName = repoName.trim();

		const result = await this.getAllFilteredData<WorkflowRunModel>(
			async (page: number, qtyPerPage?: number) => {
				return await this.getWorkflowRuns(
					repoName,
					this.AnyBranch,
					WorkflowEvent.any,
					WorkflowRunStatus.any,
					page,
					qtyPerPage,
				);
			},
			1, // Start page
			100, // Qty per page,
			(pageOfData: WorkflowRunModel[]) => {
				return pageOfData.filter((workflowRun: WorkflowRunModel) => {
					const createdTime = new Date(workflowRun.created_at).getTime();
					const startTime = startDate.getTime();
					const endTime = endDate.getTime();

					return createdTime >= startTime && createdTime <= endTime;
				});
			},
		);

		return result;
	}

	/**
	 * Gets all workflow runs for a repository with a name that matches the given {@link repoName} and
	 * that matches the given {@link title}.
	 * @param repoName The name of the repository.
	 * @param title The title of the workflow runs.
	 * @returns The workflow runs.
	 */
	public async getAllWorkflowRunsByTitle(repoName: string, title: string): Promise<WorkflowRunModel[]> {
		const funcName = "getAllWorkflowRunsByTitle";
		Guard.isNullOrEmptyOrUndefined(repoName, funcName, "repoName");
		Guard.isNullOrEmptyOrUndefined(title, funcName, "title");

		repoName = repoName.trim();
		title = title.trim();

		return await this.getAllFilteredData<WorkflowRunModel>(
			async (page: number, qtyPerPage?: number) => {
				return await this.getWorkflowRuns(
					repoName,
					this.AnyBranch,
					WorkflowEvent.any,
					WorkflowRunStatus.any,
					page,
					qtyPerPage,
				);
			},
			1, // Start page
			100, // Qty per page,
			(pageOfData: WorkflowRunModel[]) => {
				return pageOfData.filter((workflowRun) => workflowRun.name.trim() === title);
			},
		);
	}

	/**
	 * Gets the first workflow run for a repository with a name that matches the given {@link repoName} and
	 * that matches the given {@link title}.
	 * @param repoName The name of the repository.
	 * @param title The title of the workflow run.
	 * @returns The workflow run.
	 */
	public async getWorkflowRunByTitle(repoName: string, title: string): Promise<WorkflowRunModel> {
		const funcName = "getWorkflowRunByTitle";
		Guard.isNullOrEmptyOrUndefined(repoName, funcName, "repoName");
		Guard.isNullOrEmptyOrUndefined(title, funcName, "title");

		repoName = repoName.trim();
		title = title.trim();

		const workflowRuns = await this.getAllDataUntil<WorkflowRunModel>(
			async (page: number, qtyPerPage?: number) => {
				return await this.getWorkflowRuns(
					repoName,
					this.AnyBranch,
					WorkflowEvent.any,
					WorkflowRunStatus.any,
					page,
					qtyPerPage,
				);
			},
			1, // Start page
			100, // Qty per page,
			(pageOfData: WorkflowRunModel[]) => {
				return pageOfData.some((workflowRun) => workflowRun.name.trim() === title);
			},
		);

		const workflowRun = workflowRuns.find((run) => run.display_title.trim() === title);

		if (workflowRun === undefined) {
			Utils.printAsGitHubError(`A workflow run with the title '${title}' was not found.`);
			Deno.exit(1);
		}

		return workflowRun;
	}

	/**
	 * Gets all workflow runs for a repository that matches the given {@link repoName} and for a pull request
	 * number that matches the given {@link prNumber}.
	 * @param repoName The name of the repository.
	 * @param prNumber The number of the pull request.
	 * @returns The workflow runs for a pull request number that matches the given {@link prNumber}.
	 * @remarks Does not require authentication.
	 */
	public async getWorkflowRunsForPR(repoName: string, prNumber: number): Promise<WorkflowRunModel[]> {
		const funcName = "getWorkflowRunsForPR";
		Guard.isNullOrEmptyOrUndefined(repoName, funcName, "repoName");
		Guard.isLessThanOne(prNumber, funcName, "prNumber");

		const result = await this.getAllDataUntil<WorkflowRunModel>(
			async (page: number, qtyPerPage?: number) => {
				return await this.getWorkflowRuns(
					repoName,
					this.AnyBranch,
					WorkflowEvent.any,
					WorkflowRunStatus.any,
					page,
					qtyPerPage,
				);
			},
			1, // Start page
			100, // Qty per page,
			(pageOfData: WorkflowRunModel[]) => {
				return pageOfData.some((workflowRun: WorkflowRunModel) => {
					const containsPRData = workflowRun.pull_requests != null && workflowRun.pull_requests.length > 0;
					const prFound = workflowRun.pull_requests.some((pr) => pr.number === prNumber);

					return containsPRData && prFound;
				});
			},
		);

		// Filter out all of the items that are for the given pr
		return result.filter((workflowRun) => workflowRun.pull_requests.some((pr) => pr.number === prNumber));
	}

	/**
	 * Gets all of the workflow runs for a repository with a name that matches the given {@link repoName} and
	 * that are for a pull request.
	 * @param repoName The name of the repository.
	 * @returns All of the workflow runs that are for a pull request.
	 */
	public async getPullRequestWorkflowRuns(repoName: string): Promise<WorkflowRunModel[]> {
		Guard.isNullOrEmptyOrUndefined(repoName, "getPullRequestWorkflowRuns", "repoName");

		return await this.getAllFilteredData<WorkflowRunModel>(
			async (page: number, qtyPerPage?: number) => {
				return await this.getWorkflowRuns(
					repoName,
					this.AnyBranch,
					WorkflowEvent.any,
					WorkflowRunStatus.any,
					page,
					qtyPerPage,
				);
			},
			1,
			100,
			(pageOfData: WorkflowRunModel[]) => {
				return pageOfData.filter((workflowRun) =>
					workflowRun.pull_requests != null && workflowRun.pull_requests.length > 0
				);
			},
		);
	}

	/**
	 * Deletes the given {@link workflowRun}.
	 * @param repoName The name of the repository.
	 * @remarks Requires authentication.
	 */
	public async deleteWorkflow(repoName: string, workflowRun: WorkflowRunModel): Promise<void> {
		Guard.isNullOrEmptyOrUndefined(repoName, "deleteWorkflow", "repoName");

		const url = `${this.baseUrl}/repos/${this.organization}/${repoName}/actions/runs/${workflowRun.id}`;

		const response: Response = await this.requestDELETE(url);

		// If there is an error
		switch (response.status) {
			case GitHubHttpStatusCodes.Forbidden:
			case GitHubHttpStatusCodes.NotFound: {
				let errorMsg = `An error occurred trying to delete the workflow run '${workflowRun.name}(${workflowRun.id})'`;
				errorMsg += `Error: ${response.status}(${response.statusText})`, Utils.printAsGitHubError(errorMsg);
				Deno.exit(1);
			}
		}
	}

	/**
	 * Executes a workflow that matches the given {@link workflowFileName} on a branch that matches the
	 * given {@link branchName} in a repository with a name that matches the given {@link repoName}.
	 * @param repoName The name of the repository.
	 * @param branchName The name of the branch.
	 * @param workflowFileName The file name of the workflow.
	 */
	public async executeWorkflow(
		repoName: string,
		branchName: string,
		workflowFileName: string,
		inputs?: [string, string][],
	): Promise<void> {
		const funcName = "executeWorkflow";
		Guard.isNullOrEmptyOrUndefined(repoName, funcName, "repoName");
		Guard.isNullOrEmptyOrUndefined(branchName, funcName, "branchName");
		Guard.isNullOrEmptyOrUndefined(workflowFileName, funcName, "workflowFileName");

		branchName = branchName.trim().toLowerCase();
		workflowFileName = workflowFileName.trim().toLowerCase();

		// If the workflow file name does not contain the correct extension
		if (!workflowFileName.endsWith(".yml") && !workflowFileName.endsWith(".yaml")) {
			let errorMsg = `The workflow file name '${workflowFileName}' does not contain the correct extension.`;
			errorMsg += `\nThe workflow file name must end with '.yml' or '.yaml'.`;
			Deno.exit(1);
		}

		let body = {};

		if (inputs === undefined) {
			inputs = [];
		}

		if (inputs.length <= 0) {
			body = { ref: branchName };
		} else {
			inputs.forEach((input) => {
				const workflowInput = input[0];

				if ((inputs?.filter((i) => workflowInput === i[0]).length ?? 0) > 1) {
					let errorMsg = `The workflow input '${workflowInput}' is duplicated.`;
					errorMsg += `\n\tWorkflow: ${workflowFileName}`;
					errorMsg += `\n\tBranch: ${branchName}`;
					errorMsg += `\n\tRepository: ${repoName}`;
					Utils.printAsGitHubError(errorMsg);
					Deno.exit(1);
				}
			});

			body = {
				ref: branchName,
				inputs: Object.fromEntries(inputs),
			};
		}

		const url = `${this.baseUrl}/repos/${this.organization}/${repoName}/actions/workflows/${workflowFileName}/dispatches`;

		const requestResponse: Response = await this.requestPOST(url, body);

		if (requestResponse.status != GitHubHttpStatusCodes.NoContent) {
			let errorMsg = "";
			switch (requestResponse.status) {
				case GitHubHttpStatusCodes.NotFound: {
					errorMsg = `The workflow '${workflowFileName}' could not be found on branch `;
					errorMsg += `'${branchName}' in the repository '${repoName}'.'`;
					errorMsg += `\n\tError: ${requestResponse.status}(${requestResponse.statusText})`;
					break;
				}
				case GitHubHttpStatusCodes.UnprocessableContent: {
					errorMsg = `The workflow '${workflowFileName}' on branch '${branchName}' in the repository `;
					errorMsg += `'${repoName}' was not processable.`;
					const githubResponse: GithubResponse = JSON.parse(await requestResponse.text());

					errorMsg += `\n\tError: ${requestResponse.status}(${requestResponse.statusText})`;
					errorMsg += `\n${githubResponse.message}\n${githubResponse.documentation_url}`;
					break;
				}
				default: {
					errorMsg = `An error occurred trying to execute the workflow '${workflowFileName}' on branch `;
					errorMsg += `'${branchName}' in the repository '${repoName}'.'`;
					errorMsg += `\n\tError: ${requestResponse.status}(${requestResponse.statusText})`;
					Utils.printAsGitHubError(errorMsg);
					break;
				}
			}

			Utils.printAsGitHubError(errorMsg);
			Deno.exit(1);
		}
	}
}

Velaptor Release Workflow

Trigger Docs Release Workflow Input:

trigger-api-docs-release:
  description: Check to trigger a release of the API Documentation website.
  required: false
  default: true
  type: boolean

Trigger Release Job

  run_api_doc_release:
    name: Run API Doc Release
    needs: [run_release, validate_version]
    if: ${{ inputs.trigger-api-docs-release == true }}
    runs-on: ubuntu-latest
    steps:
      - name:  Checkout Repo
        uses: actions/checkout@v5

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

      - name: Execute API Release Workflow
        run: |
          $scriptUrl = "${{ github.workspace }}/.github/cicd/scripts/trigger-api-docs-release.ts";

          deno run `
            --allow-net `
            $scriptUrl `
            "${{ vars.DOC_SITE_REPO_NAME }}" `
            "${{ vars.DOC_SITE_RELEASE_BRANCH }}" `
            "${{ vars.DOC_SITE_API_RELEASE_WORKFLOW_NAME }}" `
            "[api-version,${{ needs.validate_version.outputs.version }}]" `
            "${{ secrets.CICD_TOKEN }}";
            
          $releasesUrl = "https://github.com/${{ vars.ORGANIZATION_NAME }}/${{ vars.DOC_SITE_REPO_NAME }}/actions/workflows/${{ vars.DOC_SITE_API_RELEASE_WORKFLOW_NAME }}";

          $notice = "An API documentation release has been triggered for the '${{ vars.DOC_SITE_REPO_NAME }}' repository."
          $notice = $notice + "`n`t${{ vars.DOC_SITE_REPO_NAME }} Releases: $releasesUrl";
          Write-Host "::notice::$notice";

Acceptance Criteria

The items to complete to satisfy the Definition of Done.

  • Trigger the docs release workflow script created.
  • Release workflow updated with workflow input and job to trigger the release workflow.

Metadata

Metadata

Labels

Type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions