Last active
November 7, 2025 16:03
-
-
Save tracker1/d74329cacbb95e69d3caa7ed6869f396 to your computer and use it in GitHub Desktop.
Get a database version string when using release-please
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env -S deno run -A --quiet | |
| // deno-lint-ignore-file no-explicit-any | |
| /******************************************************************************* | |
| Deno script to output a tagged version for use with deployments. | |
| deno run -A --quiet _scripts/get-db-version.ts | |
| Inputs: | |
| --baseversion "BASE_VERSION_OVERRIDE" | |
| example "1.1.19" | |
| --githash "GITHASH_OVERRIDE" | |
| --timesamp "TIMESTAMP_STRING_OVERRIDE" | |
| Outputs: | |
| A version string "${manifest-version}-${git-shorrt-hash}-${timestamp}" | |
| manifest-version: from input or Read from ../release-please-manifest.json | |
| git-short-hash: from input or determined from `git rev-parse` | |
| timestamp: from input or base323 encoded from | |
| `+"YYYYMMDDhhmmss"` as an integer | |
| Warning: run `deno check` first to avoid additional deno output | |
| Desting: deno test --coverage --allow-run _scripts/get-db-version.ts | |
| *******************************************************************************/ | |
| import { parseArgs } from "jsr:@std/cli/parse-args"; | |
| import { git, GitCommand } from "jsr:@gnome/git-cli"; | |
| // testing | |
| import { assertEquals, assertMatch } from "jsr:@std/assert"; | |
| /******************************************************************************/ | |
| type IFileReaderSync = (path: string) => string; | |
| type IGitCliFunction = (args: string) => GitCommand; | |
| function getReleaseVersion(readFile: IFileReaderSync, baseversion?: string) { | |
| if (baseversion) { | |
| return baseversion; | |
| } | |
| const __dirname = import.meta.dirname; | |
| return JSON.parse( | |
| readFile(`${__dirname}/../release-please-manifest.json`), | |
| )["."]; | |
| } | |
| function getTimestamp(timestamp?: string) { | |
| if (timestamp) { | |
| return timestamp; | |
| } | |
| return (+(new Date().toJSON().replace(/\D/g, "").substring(0, 14))) | |
| .toString(32).toLowerCase(); | |
| } | |
| async function getGitHash(gitCli: IGitCliFunction, githash?: string) { | |
| if (!githash) { | |
| const { code, stdout /*, stderr*/ } = await gitCli("rev-parse HEAD"); | |
| if (code != 0) return "unknown"; | |
| githash = new TextDecoder().decode(stdout).trim(); | |
| } | |
| return githash.substring(0, 7); | |
| } | |
| function formatVersionString(ver: string, shorthash: string, ts: string) { | |
| return `${ver}-${shorthash}.${ts}`; | |
| } | |
| async function getVersionString( | |
| readFile: IFileReaderSync, | |
| gitCli: IGitCliFunction, | |
| baseversion?: string, | |
| githash?: string, | |
| timestamp?: string, | |
| ) { | |
| const ver = getReleaseVersion(readFile, baseversion); | |
| const hash = await getGitHash(gitCli, githash); | |
| const ts = getTimestamp(timestamp); | |
| return formatVersionString(ver, hash, ts); | |
| } | |
| async function getVersionStringFromArguments( | |
| readFile: IFileReaderSync, | |
| git: IGitCliFunction, | |
| inputArgs: string[], | |
| ) { | |
| const args = parseArgs(inputArgs, { | |
| string: ["baseversion", "githash", "timestamp"], | |
| }); | |
| const version = await getVersionString( | |
| readFile, | |
| git, | |
| args.baseversion, | |
| args.githash, | |
| args.timestamp, | |
| ); | |
| return version; | |
| } | |
| /******************************************************************************* | |
| MAIN ENTRY -- If called directly -- executes workflow | |
| *******************************************************************************/ | |
| // deno-coverage-ignore-start | |
| if (import.meta.main) { | |
| console.log( | |
| await getVersionStringFromArguments(Deno.readTextFileSync, git, Deno.args), | |
| ); | |
| } | |
| // deno-coverage-ignore-stop | |
| /******************************************************************************* | |
| * Unit Tests | |
| */ | |
| Deno.test("Can override all inputs (Happy Path)", async () => { | |
| // arrange | |
| const bv = "1.1.1"; | |
| const gh = "abcdefghijklmnop"; | |
| const ts = "12345678"; | |
| const args = [ | |
| "--baseversion", | |
| bv, | |
| "--githash", | |
| gh, | |
| "--timestamp", | |
| ts, | |
| ]; | |
| // act | |
| const result = await getVersionStringFromArguments( | |
| null as any, | |
| null as any, | |
| args, | |
| ); | |
| // assert | |
| assertEquals(result, `${bv}-${gh.substring(0, 7)}.${ts}`); | |
| }); | |
| Deno.test("Will run without parameters", async () => { | |
| const readFile = () => `{".":"1.1.1"}`; | |
| const gitCli = () => | |
| Promise.resolve({ | |
| stdout: new TextEncoder().encode("testing"), | |
| stdErr: new Uint8Array(0), | |
| code: 0, | |
| signal: undefined, | |
| success: true, | |
| }); | |
| const result = await getVersionStringFromArguments( | |
| readFile, | |
| gitCli as any, | |
| [], | |
| ); | |
| assertMatch(result, /1\.1\.1\-(\w{7})\.(\w{8})/); | |
| }); | |
| Deno.test("Will handle missing git", async () => { | |
| const readFile = () => `{".":"1.1.1"}`; | |
| const gitCli = () => | |
| Promise.resolve({ | |
| stdout: new Uint8Array(0), | |
| stdErr: new TextEncoder().encode( | |
| "fatal: not a git repository (or any of the parent directories): .git\n", | |
| ), | |
| code: 128, | |
| signal: undefined, | |
| success: false, | |
| }); | |
| const result = await getVersionStringFromArguments( | |
| readFile as any, | |
| gitCli as any, | |
| [], | |
| ); | |
| assertMatch(result, /1\.1\.1\-unknown\.(\w{8})/); | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # In my early steps... | |
| # I'm using powershell because I'm releasing on windows currently in a self-hosted runner | |
| # Writing to a file is because for some reason in the action runner, variable capture doesn't work. | |
| jobs: | |
| deploy_db: | |
| ... | |
| steps: | |
| - name: Install Deno Runtime | |
| uses: denoland/setup-deno@v2 | |
| with: | |
| deno-version: v2.x | |
| - name: Checkout Project Code | |
| uses: actions/checkout@v4 | |
| - id: dbver | |
| name: Get Database Patch Version | |
| shell: pwsh | |
| run: | | |
| deno run -A --quiet _scripts/get-db-version.ts --githash "${{ github.sha }}" > dbver.txt 2>&1 | |
| $dbver = Get-Content -Path "dbver.txt" -Raw | |
| rm dbver.txt | |
| echo "DBVER=$dbver" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
| echo "Database Version: $dbver" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment