Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
packages/core/hosted export-ignore
3 changes: 3 additions & 0 deletions .github/workflows/ci-rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Validate CLI version bump policy
run: bash scripts/ci/validate-cli-version-bump.sh

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9
with:
Expand Down
44 changes: 37 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,24 @@ jobs:
- name: Run repo hygiene
run: node scripts/ci/repo-hygiene.mjs

workflow-lint:
name: workflow-lint
runs-on: ubuntu-24.04
timeout-minutes: 10
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
# actionlint parses the shell inside every `run:` block. The repo's other
# workflow checks match text and cannot: a stray `fi` made
# mirror-cli-r2.yml's first step a bash syntax error and sat on `dev`
# undetected for two days (ATO-1934).
- name: Lint workflows
run: bash scripts/ci/lint-workflows.sh

package-metadata:
name: package-metadata
runs-on: ubuntu-24.04
Expand Down Expand Up @@ -71,13 +89,15 @@ jobs:
- name: Setup pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
corepack prepare "pnpm@${PNPM_VERSION}" --activate
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Run release-policy guardrails
run: node scripts/ci/release-policy.mjs
- name: Run release-policy unit tests
run: node --test scripts/ci/__tests__/release-policy.test.mjs
- name: Test public release input wiring
run: node --test scripts/ci/__tests__/public-release-inputs.test.mjs
# Every surface that can write a verbatim memory must be able to stamp
# content_class. The 0.2.0 release fixed Hermes for Core's raw-content
# policy and missed OpenClaw, whose published plugin could not perform a
Expand Down Expand Up @@ -114,11 +134,14 @@ jobs:
- name: Setup pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
corepack prepare "pnpm@${PNPM_VERSION}" --activate
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run affected build, typecheck, lint, and self-contained tests
run: node scripts/ci/run-root-script.mjs ci:affected
- name: Run private hosted Core compatibility tests
if: github.repository == 'atomicstrata/atomicmemory-internal'
run: bash packages/core/hosted/__tests__/run.sh

code-health:
name: code-health
Expand All @@ -136,7 +159,7 @@ jobs:
- name: Setup pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
corepack prepare "pnpm@${PNPM_VERSION}" --activate
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run code health checks
Expand All @@ -158,7 +181,7 @@ jobs:
- name: Setup pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
corepack prepare "pnpm@${PNPM_VERSION}" --activate
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run package dry-runs through turbo
Expand All @@ -180,7 +203,7 @@ jobs:
- name: Setup pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
corepack prepare "pnpm@${PNPM_VERSION}" --activate
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run docs contract
Expand Down Expand Up @@ -210,7 +233,7 @@ jobs:
- name: Setup pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
corepack prepare "pnpm@${PNPM_VERSION}" --activate
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run public integration smoke
Expand Down Expand Up @@ -273,13 +296,20 @@ jobs:
- name: Setup pnpm
run: |
corepack enable
corepack prepare pnpm@${PNPM_VERSION} --activate
corepack prepare "pnpm@${PNPM_VERSION}" --activate
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Run security compliance contract tests
run: |
pnpm run test:security-compliance
pnpm run test:release-cli-version
pnpm run test:cli-version-bump
pnpm run test:mirror-cli-r2
pnpm run test:install-cli
pnpm run test:install-cli-internal
pnpm run test:cli-install-smoke
pnpm run test:cli-install-smoke-reporter
pnpm run test:reconcile-internal-release
pnpm run test:release-policy
pnpm run test:guards
pnpm run security-compliance
140 changes: 140 additions & 0 deletions .github/workflows/cli-install-smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
name: CLI Fresh Install Smoke

# Installs the published `am` from cli-internal-latest (or a dispatch-selected
# tag such as cli-canary-latest) onto a clean runner and
# proves it works — the artifact-level counterpart to core-docker-smoke.
#
# The fixture tests (scripts/__tests__/install-cli*.test.sh) drive the installer
# with a fake gh and a fake am, so they prove installer logic and nothing about
# the release. internal-cli-release.yml's own "Native smoke" untars the binary
# on the machine that just built it, bypassing both installers. Neither notices
# if cli-internal-latest is deleted, if its tarballs and version.json disagree,
# or if the shipped binary cannot start without a Rust toolchain present.
#
# One job per published target, so a broken tarball is attributed to its
# platform rather than to "the release".
#
# Repo guard: this file is mirrored into the public repo, and the release it
# installs from is private. Jobs run ONLY on atomicstrata/atomicmemory-internal.

on:
schedule:
# Daily. The release only changes on pushes to main, so this is watching for
# rot — a deleted release, a missing asset, a runner image that stops
# satisfying the binary — not for churn.
- cron: "20 6 * * *"
workflow_dispatch:
inputs:
tag:
description: "Release tag to install (default: cli-internal-latest; use cli-canary-latest for canary)"
required: false
default: cli-internal-latest
type: string

permissions:
contents: read

defaults:
run:
shell: bash

jobs:
install-smoke:
name: install-smoke ${{ matrix.target }}
if: github.repository == 'atomicstrata/atomicmemory-internal'
runs-on: ${{ matrix.runner }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
include:
- target: aarch64-apple-darwin
runner: macos-15
- target: x86_64-apple-darwin
runner: macos-15-intel
- target: x86_64-unknown-linux-gnu
runner: ubuntu-24.04
- target: aarch64-unknown-linux-gnu
runner: ubuntu-24.04-arm
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false

# GITHUB_TOKEN with contents:read can read this repository's own release
# assets, so no PAT is involved.
- name: Fresh install smoke
env:
GH_TOKEN: ${{ github.token }}
AM_INTERNAL_TAG: ${{ inputs.tag || 'cli-internal-latest' }}
run: bash scripts/cli-install-smoke.sh

report:
name: report scheduled status
if: always() && github.repository == 'atomicstrata/atomicmemory-internal'
needs: install-smoke
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions:
contents: read
issues: write
steps:
# A nightly nobody is told about is not a gate. Opens one self-clearing
# issue on failure and closes it on the next green run.
#
# Gated on `schedule` so a manual dispatch — which an engineer is already
# watching, and which may target an arbitrary tag — can neither open nor
# close the nightly's issue. `cancelled` is skipped because a cancelled
# run is not evidence either way. continue-on-error keeps a reporter fault
# from failing a run that actually passed, which would invert the signal
# this exists to protect.
- name: Open or close the failure issue
if: github.event_name == 'schedule' && needs.install-smoke.result != 'cancelled'
continue-on-error: true
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
SMOKE_RESULT: ${{ needs.install-smoke.result }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
LABEL: cli-install-smoke
run: |
set -euo pipefail
# Ask about this label rather than listing and grepping: a repo with
# more labels than the page size would look like it has none, and the
# create would then fail on a label that already exists.
if ! gh label list --search "$LABEL" --json name --jq '.[].name' | grep -qx "$LABEL"; then
gh label create "$LABEL" --color B60205 \
--description "Nightly fresh-install smoke for the published am CLI"
fi
existing="$(gh issue list --label "$LABEL" --state open \
--limit 1 --json number --jq '.[0].number // empty')"

if [ "$SMOKE_RESULT" = "success" ]; then
if [ -n "$existing" ]; then
gh issue close "$existing" \
--comment "Fresh-install smoke is green again: ${RUN_URL}"
echo "closed #${existing}"
else
echo "green, nothing open"
fi
exit 0
fi

body="Nightly fresh-install smoke for \`cli-internal-latest\` reported \`${SMOKE_RESULT}\`.

Run: ${RUN_URL}

Each job installs the published \`am\` into a throwaway \$HOME on a clean
runner. A failure means the release as published does not install, not
that a test is flaky — the job list names the affected target.

This issue closes itself on the next green scheduled run."
if [ -n "$existing" ]; then
gh issue comment "$existing" --body "Still failing: ${RUN_URL}"
echo "commented on #${existing}"
else
gh issue create --label "$LABEL" \
--title "Nightly CLI fresh-install smoke is failing" \
--body "$body"
fi
Loading
Loading