-
Notifications
You must be signed in to change notification settings - Fork 0
ci: enforce RLMX release channel contract #103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| # RLMX Release Contract | ||
|
|
||
| RLMX follows the Hermes/Genie install/update shape: | ||
|
|
||
| - `scripts/install.sh` is the canonical installer. | ||
| - `rlmx update` updates an installed checkout by fetching the latest public `main` commits. | ||
| - npm is SDK-only distribution. npm is not the canonical end-user CLI release channel. | ||
| - The canonical release boundary is a PR merge from `dev` to `main`. | ||
|
|
||
| ## Channels | ||
|
|
||
| ### CLI / application channel | ||
|
|
||
| The CLI is git-installed: | ||
|
|
||
| 1. `install.sh` clones or refreshes the public repository. | ||
| 2. It checks out `main`. | ||
| 3. It installs dependencies. | ||
| 4. It builds local `dist/`. | ||
| 5. It links the `rlmx` executable into the user's bin directory. | ||
|
|
||
| After install, `rlmx update` performs the same update path in-place against `origin/main`. | ||
|
|
||
| ### npm channel | ||
|
|
||
| The npm package is SDK-only: | ||
|
|
||
| - npm publishes library/SDK artifacts for programmatic consumers. | ||
| - npm dist-tags are not the canonical CLI release signal. | ||
| - `rlmx --version` reports the package/runtime version embedded in the checkout, but CLI freshness is primarily determined by the git commit on `main`. | ||
|
|
||
| ## Main release boundary | ||
|
|
||
| `main` is the canonical release branch. | ||
|
|
||
| A release happens when a PR merges from `dev` to `main`: | ||
|
|
||
| 1. CI passes on the PR. | ||
| 2. The merge lands on `main`. | ||
| 3. `main` becomes the install/update target. | ||
| 4. `install.sh` and `rlmx update` fetch that commit. | ||
| 5. GitHub release metadata may be created from the package version, but it is not the install authority. | ||
|
|
||
| ## Coherence invariants | ||
|
|
||
| - Public git tags and GitHub Releases must not lie about package contents. | ||
| - If a tag is named `vX`, the target commit's `package.json` and `src/version.ts` must also be `X`. | ||
| - `rlmx update` must never use npm to update the CLI application. | ||
| - npm publishing must not create or imply a CLI release. | ||
| - Deployment-specific private policy must stay outside public RLMX. | ||
|
|
||
| ## Update semantics | ||
|
|
||
| `rlmx update`: | ||
|
|
||
| - Runs from the installed repository root. | ||
| - Fetches `origin main --tags`. | ||
| - Refuses to overwrite local changes unless explicitly forced. | ||
| - Resets the checkout to `origin/main` for managed installs. | ||
| - Runs dependency install and build. | ||
| - Reports old commit, new commit, and version. | ||
|
|
||
| This mirrors the practical Hermes model: the installer owns the app checkout; the app update command refreshes that checkout. | ||
|
|
||
| ## Workflow implementation | ||
|
|
||
| The release system follows this contract: | ||
|
|
||
| - `CI` builds, typechecks, tests, and runs an install/update smoke against a temporary git `main` remote. | ||
| - `SDK Package` publishes npm artifacts for programmatic consumers only. | ||
| - The npm manifest does not expose a `bin`, so npm does not act as the canonical CLI installer. | ||
| - `Release Metadata` may create GitHub Releases from the package version, but only as coherent metadata. | ||
| - The rolling `dev` → `main` PR states that merging it is the application release boundary. |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,43 @@ | ||||||||||||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| RLMX_REPO_URL="${RLMX_REPO_URL:-https://github.com/automagik-dev/rlmx.git}" | ||||||||||||||||||||||||
| RLMX_BRANCH="${RLMX_BRANCH:-main}" | ||||||||||||||||||||||||
| RLMX_INSTALL_DIR="${RLMX_INSTALL_DIR:-$HOME/.rlmx/rlmx}" | ||||||||||||||||||||||||
| RLMX_BIN_DIR="${RLMX_BIN_DIR:-$HOME/.local/bin}" | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| echo "==> Installing RLMX" | ||||||||||||||||||||||||
| echo "repo: $RLMX_REPO_URL" | ||||||||||||||||||||||||
| echo "branch: $RLMX_BRANCH" | ||||||||||||||||||||||||
| echo "dir: $RLMX_INSTALL_DIR" | ||||||||||||||||||||||||
| echo "bin: $RLMX_BIN_DIR" | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| mkdir -p "$RLMX_BIN_DIR" "$(dirname "$RLMX_INSTALL_DIR")" | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| if [ -d "$RLMX_INSTALL_DIR/.git" ]; then | ||||||||||||||||||||||||
| echo "==> Existing checkout found; refreshing" | ||||||||||||||||||||||||
| git -C "$RLMX_INSTALL_DIR" fetch origin "$RLMX_BRANCH" --tags | ||||||||||||||||||||||||
| git -C "$RLMX_INSTALL_DIR" checkout "$RLMX_BRANCH" | ||||||||||||||||||||||||
| git -C "$RLMX_INSTALL_DIR" reset --hard "origin/$RLMX_BRANCH" | ||||||||||||||||||||||||
|
Comment on lines
+17
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Existing installs ignore On the refresh path, the script always fetches from the checkout’s current Suggested fix if [ -d "$RLMX_INSTALL_DIR/.git" ]; then
echo "==> Existing checkout found; refreshing"
+ git -C "$RLMX_INSTALL_DIR" remote set-url origin "$RLMX_REPO_URL"
git -C "$RLMX_INSTALL_DIR" fetch origin "$RLMX_BRANCH" --tags
git -C "$RLMX_INSTALL_DIR" checkout "$RLMX_BRANCH"
git -C "$RLMX_INSTALL_DIR" reset --hard "origin/$RLMX_BRANCH"
else📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
| else | ||||||||||||||||||||||||
| if [ -e "$RLMX_INSTALL_DIR" ]; then | ||||||||||||||||||||||||
| echo "error: $RLMX_INSTALL_DIR exists but is not a git checkout" >&2 | ||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||
| echo "==> Cloning" | ||||||||||||||||||||||||
| git clone --branch "$RLMX_BRANCH" "$RLMX_REPO_URL" "$RLMX_INSTALL_DIR" | ||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| cd "$RLMX_INSTALL_DIR" | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| echo "==> Installing dependencies" | ||||||||||||||||||||||||
| npm ci | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| echo "==> Building" | ||||||||||||||||||||||||
| npm run build | ||||||||||||||||||||||||
|
Comment on lines
+33
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When this installer runs in an environment with Useful? React with 👍 / 👎. |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| ln -sfn "$RLMX_INSTALL_DIR/dist/src/cli.js" "$RLMX_BIN_DIR/rlmx" | ||||||||||||||||||||||||
| chmod +x "$RLMX_INSTALL_DIR/dist/src/cli.js" | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| echo "==> Installed" | ||||||||||||||||||||||||
| "$RLMX_BIN_DIR/rlmx" --version | ||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the existing checkout has any local modifications or untracked files that conflict,
git checkoutwithout the force flag will fail and abort the installation. Usingcheckout -fensures that the checkout succeeds by discarding local changes, which is the expected behavior for a clean managed refresh.