diff --git a/.gitea/workflows/build-version-check.yml b/.gitea/workflows/build-version-check.yml new file mode 100644 index 0000000..f958f5c --- /dev/null +++ b/.gitea/workflows/build-version-check.yml @@ -0,0 +1,25 @@ +name: Build and Push Version Check Action + +on: + push: + paths: + - version-check/** + - .gitea/workflows/build-version-check.yml + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build Docker image + run: | + docker build -t git.cyborggrizzly.com/BearMetal/ci-actions/version-check:latest ./version-check + + - name: Log in to Gitea registry + run: | + echo "${{ secrets.REGISTRY_TOKEN }}" | docker login git.cyborggrizzly.com -u ${{ secrets.REGISTRY_USER }} --password-stdin + + - name: Push to registry + run: | + docker push git.cyborggrizzly.com/BearMetal/ci-actions/version-check:latest diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..9cb4e93 --- /dev/null +++ b/deno.json @@ -0,0 +1,8 @@ +{ + "tasks": { + "dev": "deno run --watch main.ts" + }, + "imports": { + "@std/assert": "jsr:@std/assert@1" + } +} \ No newline at end of file diff --git a/version-check/Dockerfile b/version-check/Dockerfile new file mode 100644 index 0000000..5c84c52 --- /dev/null +++ b/version-check/Dockerfile @@ -0,0 +1,13 @@ +# Build the binary +FROM denoland/deno:latest AS builder + +WORKDIR /src +COPY main.ts . + +RUN deno compile --allow-read --allow-run --output version-check main.ts + +# Final image +FROM alpine:latest +COPY --from=builder /src/version-check /usr/local/bin/version-check + +ENTRYPOINT ["/usr/local/bin/version-check"] diff --git a/version-check/README.md b/version-check/README.md new file mode 100644 index 0000000..e69de29 diff --git a/version-check/action.yml b/version-check/action.yml new file mode 100644 index 0000000..ebcc615 --- /dev/null +++ b/version-check/action.yml @@ -0,0 +1,5 @@ +name: Version Check & Tag +description: Ensures version correctness and creates missing git tags +runs: + using: "docker" + image: git.cyborggrizzly.com/BearMetal/ci-actions/version-check:latest diff --git a/version-check/main.ts b/version-check/main.ts new file mode 100644 index 0000000..3552b6a --- /dev/null +++ b/version-check/main.ts @@ -0,0 +1,50 @@ +const decoder = new TextDecoder(); +const denoJson = JSON.parse(await Deno.readTextFile("deno.json")); +let version = denoJson.version; +if (!version) { + console.error("Missing 'version' in deno.json"); + Deno.exit(1); +} + +const branch = Deno.env.get("GITHUB_REF")?.replace("refs/heads/", "") ?? ""; +if (branch.startsWith("prerelease-")) { + const suffix = branch.replace("prerelease-", ""); + const base = version.split("-")[0]; + const expected = `${base}-${suffix}`; + if (version !== expected) { + denoJson.version = expected; + await Deno.writeTextFile("deno.json", JSON.stringify(denoJson, null, 2)); + await run("git", ["config", "user.name", "CI"]); + await run("git", ["config", "user.email", "ci@cyborggrizzly.com"]); + await run("git", ["add", "deno.json"]); + await run("git", [ + "commit", + "-m", + `fix: sync version with branch ${branch}`, + ]); + await run("git", ["push"]); + version = expected; + } +} + +const tag = `v${version}`; +try { + await run("git", ["rev-parse", tag]); + console.log(`Tag ${tag} already exists.`); +} catch { + await run("git", ["tag", tag]); + await run("git", ["push", "origin", tag]); +} + +async function run(cmd: string, args: string[]) { + const command = new Deno.Command(cmd, { + args, + stdout: "piped", + stderr: "piped", + }); + const status = await command.output(); + if (!status.success) { + const err = decoder.decode(await status.stderr); + throw new Error(`Command failed: ${cmd} ${args.join(" ")}\n${err}`); + } +}