Skip to content

Commit

Permalink
feat: output new release version if one made (#31)
Browse files Browse the repository at this point in the history
## Pull Request Description

### Overview

This pull request introduces a new feature that outputs the new release
version when a release is created in GitHub Actions.

This is a feature that’s good to have, but I mostly implemented it to
have a integration test for pre-release versions.

### Changes Made

- **Feature Addition**: Added functionality to output the new release
version when a release is made in GitHub Actions. This helps users
easily identify the current version without needing to check additional
logs or files.
- **Testing**: Implemented tests to ensure that the pre-release version
is correctly created and asserted during the release process. This
ensures the reliability of the new output feature.

<!-- branch-stack -->

- `alpha`
  - \#31 :point\_left:
  • Loading branch information
levibostian authored Oct 28, 2024
1 parent 281d843 commit 59520bd
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 4 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,18 @@ Some git commits that you push to your deployment branch should be released (fea

If your team is not used to using a special format for git commit messages, you may find [this tool useful](https://github.com/levibostian/action-conventional-pr-linter) to lint pull requests before you click *Squash and merge* and perform a deployment.

🎊 Congrats! You're all setup for automated deployments!

*Tip:* We suggest checking out [how to create pre-production releases](#create-prerelease-versions) to see if this is something you're interested in.

> Note: In the future, we plan on allowing you to customize how git commits are analyzed so you can use a git commit message format your team decides. Until then, you must use conventional commits format.

# Outputs

This tool provides you with outputs to help you understand what happened during the deployment process.

* `new_release_version` - If a new release was created, this is the version of that release.

# Configuration

Customize this tool to work as you wish.
Expand Down
6 changes: 6 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ inputs:
description: 'Configure the behavior when analyzing commits.'
default: ''

outputs:
new_release_version:
description: 'If a new release was created, this is the version of that release.'
value: ${{ steps.deployment.outputs.new_release_version }}

runs:
using: "composite"
steps:
Expand All @@ -32,6 +37,7 @@ runs:
#
# The directories we are giving permission to read and write to are the temp directories for all of the OSes that GitHub Actions supports. /tmp for linux and /var/folders for macOS.
run: deno run --allow-env=GITHUB_REF,DRY_RUN,GITHUB_REPOSITORY,INPUT_GITHUB_TOKEN,INPUT_DEPLOY_COMMANDS,INPUT_ANALYZE_COMMITS_CONFIG --allow-net="api.github.com" --allow-run --allow-read="/tmp,/var/folders" --allow-write="/tmp,/var/folders" https://raw.githubusercontent.com/levibostian/new-deployment-tool/${{ inputs.version }}/index.ts
id: deployment
shell: bash
env:
DRY_RUN: ${{ inputs.dry_run_mode }}
Expand Down
74 changes: 71 additions & 3 deletions deploy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import {
} from "./lib/steps/get-commits-since-latest-release.ts";
import {
DetermineNextReleaseStep,
DetermineNextReleaseStepConfig,
} from "./lib/steps/determine-next-release.ts";
import { CreateNewReleaseStep } from "./lib/steps/create-new-release.ts";
import { DeployStep } from "./lib/steps/deploy.ts";
import { getLogMock } from "./lib/log.test.ts";
import { GitHubActions } from "./lib/github-actions.ts";

describe("run the tool", () => {
describe("run the tool in different scenarios", () => {
afterEach(() => {
restore();
});
Expand Down Expand Up @@ -82,6 +83,63 @@ describe("run the tool", () => {
});
});

describe("test github actions output", () => {
it("should set new release version output when a new release is created", async () => {
const { githubActionsSetOutputMock } = await setupTestEnvironmentAndRun({
commitsSinceLatestRelease: [new GitHubCommitFake({
message: "feat: trigger a release",
sha: "trigger-release",
})],
nextReleaseVersion: "1.0.0",
});

assertEquals(
githubActionsSetOutputMock.calls[0].args[0].key,
"new_release_version"
);
assertEquals(
githubActionsSetOutputMock.calls[0].args[0].value,
"1.0.0"
);
})
it("should not set new release version output when no new release is created", async () => {
const { githubActionsSetOutputMock } = await setupTestEnvironmentAndRun({
commitsSinceLatestRelease: [],
nextReleaseVersion: "1.0.0",
});

assertEquals(
githubActionsSetOutputMock.calls.length,
0
);
})
it("should set new pre-release version output when a new pre-release is created", async () => {
const { githubActionsSetOutputMock } = await setupTestEnvironmentAndRun({
commitsSinceLatestRelease: [new GitHubCommitFake({
message: "feat: trigger a release",
sha: "trigger-release",
})],
nextReleaseVersion: "1.0.0-beta.1",
determineNextReleaseStepConfig: {
branches: [{
branch_name: 'main',
prerelease: true,
version_suffix: 'beta'
}]
},
});

assertEquals(
githubActionsSetOutputMock.calls[0].args[0].key,
"new_release_version"
);
assertEquals(
githubActionsSetOutputMock.calls[0].args[0].value,
"1.0.0-beta.1"
);
})
})

describe("user facing logs", () => {
it("given no commits will trigger a release, expect logs to easily communicate that to the user", async (t) => {
const { logMock } = await setupTestEnvironmentAndRun({
Expand Down Expand Up @@ -140,11 +198,13 @@ const setupTestEnvironmentAndRun = async ({
commitsSinceLatestRelease,
nextReleaseVersion,
gitCommitCreatedDuringDeploy,
determineNextReleaseStepConfig,
}: {
latestRelease?: GitHubRelease;
commitsSinceLatestRelease?: GitHubCommit[];
nextReleaseVersion?: string;
gitCommitCreatedDuringDeploy?: GitHubCommit;
determineNextReleaseStepConfig?: DetermineNextReleaseStepConfig;
}) => {
Deno.env.set("GITHUB_REF", "refs/heads/main");
Deno.env.set("GITHUB_REPOSITORY", "levibostian/new-deployment-tool");
Expand Down Expand Up @@ -199,7 +259,14 @@ const setupTestEnvironmentAndRun = async ({
githubActions,
"getDetermineNextReleaseStepConfig",
() => {
return undefined;
return determineNextReleaseStepConfig
},
);
const githubActionsSetOutputMock = stub(
githubActions,
"setOutput",
() => {
return;
},
);

Expand All @@ -220,6 +287,7 @@ const setupTestEnvironmentAndRun = async ({
deployStepMock,
createNewReleaseStepMock,
logMock,
githubActionsGetDetermineNextReleaseStepConfigMock
githubActionsGetDetermineNextReleaseStepConfigMock,
githubActionsSetOutputMock,
};
};
2 changes: 2 additions & 0 deletions deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,6 @@ export const run = async ({
log.notice(
`🎉 Congratulations! The deployment process has completed. Bye-bye 👋!`,
);

githubActions.setOutput({key: "new_release_version", value: nextReleaseVersion});
};
20 changes: 20 additions & 0 deletions lib/github-actions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,24 @@ Deno.test("getDetermineNextReleaseStepConfig throws error when env variable is s
},
Error,
);
});

Deno.test("getDetermineNextReleaseStepConfig throws error when provide an invalid JSON format", () => {
const givenConfig = `
{
'branches': [
{branch_name: 'main', prerelease: false},
{branch_name: 'beta', prerelease: true},
{branch_name: 'alpha', prerelease: true}
]
}
`
Deno.env.set("INPUT_ANALYZE_COMMITS_CONFIG", givenConfig);
const githubActions = new GitHubActionsImpl();
assertThrows(
() => {
githubActions.getDetermineNextReleaseStepConfig();
},
Error,
);
});
12 changes: 11 additions & 1 deletion lib/github-actions.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { DetermineNextReleaseStepConfig } from "./steps/determine-next-release.ts";
import * as log from './log.ts';
import * as githubActions from 'npm:@actions/core';

export interface GitHubActions {
getDetermineNextReleaseStepConfig(): DetermineNextReleaseStepConfig | undefined;
setOutput({key, value}: {key: string, value: string}): void;
}

export class GitHubActionsImpl implements GitHubActions {
getDetermineNextReleaseStepConfig(): DetermineNextReleaseStepConfig | undefined {
const githubActionInputKey = "analyze_commits_config";

const determineNextReleaseStepConfig = Deno.env.get(`INPUT_${githubActionInputKey.toUpperCase()}`);
const determineNextReleaseStepConfig = this.getInput(githubActionInputKey)
if (!determineNextReleaseStepConfig) {
return undefined;
}
Expand All @@ -24,4 +26,12 @@ export class GitHubActionsImpl implements GitHubActions {
throw new Error();
}
}

setOutput({key, value}: {key: string, value: string}): void {
githubActions.setOutput(key, value);
}

private getInput(key: string): string {
return githubActions.getInput(key);
}
}

0 comments on commit 59520bd

Please sign in to comment.