Add CalVer release workflow with DotSlash
Builds on macos-latest, tags with CalVer (YYYY-MM-DD+SHORT_SHA), and
publishes a GitHub release with the aarch64-apple-darwin tarball. A
second job runs facebook/dotslash-publish-release to generate a
DotSlash file from the release artifact. Both CI and release workflows
target the rewrite branch.
build.rs sets RAMEKIN_VERSION: CI provides CalVer, local builds
default to dev+COMMIT. The --version flag reports it.
Assisted-by: Claude Opus 4.6 via pi
diff --git a/.github/dotslash-config.json b/.github/dotslash-config.json
new file mode 100644
index 0000000..5c346e7
--- /dev/null
+++ b/.github/dotslash-config.json
@@ -0,0 +1,12 @@
+{
+ "outputs": {
+ "ramekin": {
+ "platforms": {
+ "macos-aarch64": {
+ "regex": "^ramekin-aarch64-apple-darwin\\.tar\\.gz$",
+ "path": "ramekin"
+ }
+ }
+ }
+ }
+}
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d602983..47d11d5 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,7 +2,7 @@ name: CI
on:
push:
- branches: [main]
+ branches: [rewrite]
pull_request:
jobs:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..fca19c7
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,62 @@
+name: Release
+
+on:
+ workflow_dispatch:
+ workflow_run:
+ workflows: [CI]
+ types: [completed]
+ branches: [rewrite]
+
+permissions:
+ contents: write
+
+jobs:
+ build:
+ if: >-
+ github.event_name == 'workflow_dispatch'
+ || github.event.workflow_run.conclusion == 'success'
+ runs-on: macos-latest
+ outputs:
+ version: ${{ steps.version.outputs.version }}
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Calculate version
+ id: version
+ run: |
+ CALVER=$(date -u +"%Y-%m-%d")
+ SHORT_SHA=$(git rev-parse --short HEAD)
+ echo "version=${CALVER}+${SHORT_SHA}" >> $GITHUB_OUTPUT
+
+ - name: Build
+ run: |
+ RAMEKIN_VERSION="${{ steps.version.outputs.version }}" cargo build --release
+ tar -czf ramekin-aarch64-apple-darwin.tar.gz -C target/release ramekin
+
+ - name: Publish
+ run: |
+ VERSION="${{ steps.version.outputs.version }}"
+ git tag "v${VERSION}"
+ git push origin "v${VERSION}"
+ gh release create "v${VERSION}" \
+ --title "v${VERSION}" \
+ --generate-notes \
+ ramekin-aarch64-apple-darwin.tar.gz
+ env:
+ GH_TOKEN: ${{ github.token }}
+
+ dotslash:
+ needs: build
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Generate DotSlash file
+ uses: facebook/dotslash-publish-release@v1
+ with:
+ config: .github/dotslash-config.json
+ tag: v${{ needs.build.outputs.version }}
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
diff --git a/build.rs b/build.rs
new file mode 100644
index 0000000..c3e5fa6
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,19 @@
+use std::process::Command;
+
+fn main() {
+ let version = std::env::var("RAMEKIN_VERSION").unwrap_or_else(|_| {
+ let commit = cmd("git", &["rev-parse", "--short", "HEAD"]);
+ format!("dev+{commit}")
+ });
+ println!("cargo:rustc-env=RAMEKIN_VERSION={version}");
+}
+
+fn cmd(program: &str, args: &[&str]) -> String {
+ Command::new(program)
+ .args(args)
+ .output()
+ .ok()
+ .and_then(|o| String::from_utf8(o.stdout).ok())
+ .map(|s| s.trim().to_string())
+ .unwrap_or_else(|| "unknown".into())
+}
diff --git a/src/main.rs b/src/main.rs
index 09e50e0..2b15bbc 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -12,8 +12,10 @@ use tracing_subscriber::{EnvFilter, fmt, prelude::*};
const DOCKERFILE: &str = include_str!("../assets/Dockerfile");
const RAMEKIN_EXTENSION: &str = include_str!("../assets/ramekin.ts");
+const VERSION: &str = env!("RAMEKIN_VERSION");
+
#[derive(Parser)]
-#[command(about = "Run a pi coding agent in a containerized environment")]
+#[command(about = "Run a pi coding agent in a containerized environment", version = VERSION)]
struct Cli {
#[command(subcommand)]
command: Option<Cmd>,