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
40 changes: 40 additions & 0 deletions .github/actions/npm-auth-preflight/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: NPM Auth Preflight
description: Validate npm authentication and report package access

inputs:
registry-url:
description: npm registry URL
required: false
default: "https://registry.npmjs.org/"
package-dir:
description: Directory containing package.json to validate
required: true
package-name:
description: Display name for error messages
required: true

runs:
using: composite
steps:
- name: Preflight npm auth
shell: bash
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
REGISTRY_URL: ${{ inputs.registry-url }}
PACKAGE_DIR: ${{ inputs.package-dir }}
PACKAGE_NAME: ${{ inputs.package-name }}
run: |
set -euo pipefail

if [[ -z "${NODE_AUTH_TOKEN:-}" ]]; then
echo "::error::NPM_TOKEN is missing. Configure a publish-capable npm token for ${PACKAGE_NAME} before rerunning release."
exit 1
fi

pushd "$PACKAGE_DIR" >/dev/null
npm config set //registry.npmjs.org/:_authToken "${NODE_AUTH_TOKEN}"
npm_user=$(npm whoami --registry "$REGISTRY_URL")
popd >/dev/null

echo "Authenticated to npm as ${npm_user}"
echo "Deferring publish permission enforcement for ${PACKAGE_NAME} to the publish step because npm access output is not stable in this workflow."
114 changes: 114 additions & 0 deletions .github/actions/npm-publish-package/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
name: NPM Publish Package
description: Publish a package to npm with retry and verification logic

inputs:
registry-url:
description: npm registry URL
required: false
default: "https://registry.npmjs.org/"
package-dir:
description: Directory containing package.json to publish
required: true
verify-attempts:
description: Number of verification attempts
required: false
default: "90"
verify-delay:
description: Delay between verification attempts in seconds
required: false
default: "10"

runs:
using: composite
steps:
- name: Publish to npm
shell: bash
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
REGISTRY_URL: ${{ inputs.registry-url }}
PACKAGE_DIR: ${{ inputs.package-dir }}
VERIFY_ATTEMPTS: ${{ inputs.verify-attempts }}
VERIFY_DELAY: ${{ inputs.verify-delay }}
run: |
set -euo pipefail

package_name=$(jq -r '.name' "${PACKAGE_DIR}/package.json")
package_version=$(jq -r '.version' "${PACKAGE_DIR}/package.json")

registry_version_exists() {
local encoded_package_name
local version_json
local published_version

encoded_package_name=$(node -e 'process.stdout.write(encodeURIComponent(process.argv[1]))' "$package_name")
version_json=$(curl --silent --show-error --fail "${REGISTRY_URL%/}/${encoded_package_name}/${package_version}" 2>/dev/null || true)

if [[ -z "$version_json" ]]; then
return 1
fi

published_version=$(jq -r '.version // empty' <<<"$version_json")
[[ "$published_version" == "$package_version" ]]
}

version_exists() {
local published_version
published_version=$(npm view "${package_name}@${package_version}" version --registry "$REGISTRY_URL" 2>/dev/null || true)

if [[ "$published_version" == "$package_version" ]]; then
return 0
fi

registry_version_exists
}

verify_version_exists() {
local attempts="$VERIFY_ATTEMPTS"
local delay_seconds="$VERIFY_DELAY"

for attempt in $(seq 1 "$attempts"); do
if version_exists; then
echo "Verified ${package_name}@${package_version} on npm"
return 0
fi

if [[ "$attempt" -eq "$attempts" ]]; then
break
fi

echo "Waiting for ${package_name}@${package_version} to appear on npm (${attempt}/${attempts})..."
sleep "$delay_seconds"
done

echo "::error::${package_name}@${package_version} is still missing from npm after publish."
return 1
}

if version_exists; then
echo "${package_name}@${package_version} already exists on npm, skipping"
exit 0
fi

publish_log=$(mktemp)

if (cd "$PACKAGE_DIR" && pnpm publish --access public --no-git-checks) 2>&1 | tee "$publish_log"; then
verify_version_exists
rm -f "$publish_log"
exit 0
fi

if grep -Eiq 'cannot publish over the previously published versions|previously published versions' "$publish_log"; then
echo "${package_name}@${package_version} was already published according to npm, skipping"
rm -f "$publish_log"
exit 0
fi

if version_exists; then
echo "${package_name}@${package_version} already exists on npm after publish attempt, skipping"
rm -f "$publish_log"
exit 0
fi

echo "::error::Failed to publish ${package_name}@${package_version}. Exact version is still missing from npm."
rm -f "$publish_log"
exit 1
12 changes: 12 additions & 0 deletions .github/actions/setup-cross-compile/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Setup Cross-Compile Linux ARM64
description: Install aarch64-linux-gnu cross-compilation toolchain

runs:
using: composite
steps:
- name: Install cross-compilation tools (aarch64-linux)
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
2 changes: 1 addition & 1 deletion .github/workflows/deploy-doc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
run: pnpm -C doc run lint

- name: Typecheck docs
run: pnpm -C doc run typecheck
run: pnpm -C doc run check:type

- name: Pull Vercel production settings
run: pnpm dlx vercel@latest pull --yes --environment=production --token="$VERCEL_TOKEN"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pull-request-doc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
run: pnpm -C doc run lint

- name: Typecheck docs
run: pnpm -C doc run typecheck
run: pnpm -C doc run check:type

- name: Build docs
run: pnpm -C doc run build
146 changes: 142 additions & 4 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ jobs:
with:
github-token: ${{ github.token }}

check:
build:
if: github.event.pull_request.draft == false
runs-on: ubuntu-24.04
timeout-minutes: 45
timeout-minutes: 20
steps:
- uses: actions/checkout@v6

Expand All @@ -74,14 +74,152 @@ jobs:
- name: Build
run: pnpm run build

lint:
if: github.event.pull_request.draft == false
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@v6

- uses: ./.github/actions/setup-node-pnpm

- uses: ./.github/actions/setup-rust
with:
cache-key: pr

- name: Build native modules
run: pnpm run build:native

- name: Lint
run: pnpm run lint

check-type:
if: github.event.pull_request.draft == false
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@v6

- uses: ./.github/actions/setup-node-pnpm

- uses: ./.github/actions/setup-rust
with:
cache-key: pr

- name: Build native modules
run: pnpm run build:native

- name: Typecheck
run: pnpm run typecheck
run: pnpm run check:type

- name: Run tests
test:
if: github.event.pull_request.draft == false
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@v6

- uses: ./.github/actions/setup-node-pnpm

- uses: ./.github/actions/setup-rust
with:
cache-key: pr

- name: Build native modules
run: pnpm run build:native

- name: Build
run: pnpm run build

- name: Run all tests
run: pnpm run test

test-sdk:
if: github.event.pull_request.draft == false
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@v6

- uses: ./.github/actions/setup-node-pnpm

- uses: ./.github/actions/setup-rust
with:
cache-key: pr

- name: Build native modules
run: pnpm run build:native

- name: SDK tests
run: pnpm turbo test --filter=@truenine/memory-sync-sdk

test-cli:
if: github.event.pull_request.draft == false
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@v6

- uses: ./.github/actions/setup-node-pnpm

- uses: ./.github/actions/setup-rust
with:
cache-key: pr

- name: Build native modules
run: pnpm run build:native

- name: CLI tests
run: pnpm turbo test --filter=@truenine/memory-sync-cli

test-mcp:
if: github.event.pull_request.draft == false
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@v6

- uses: ./.github/actions/setup-node-pnpm

- uses: ./.github/actions/setup-rust
with:
cache-key: pr

- name: Build native modules
run: pnpm run build:native

- name: MCP tests
run: pnpm turbo test --filter=@truenine/memory-sync-mcp

test-libraries:
if: github.event.pull_request.draft == false
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@v6

- uses: ./.github/actions/setup-node-pnpm

- uses: ./.github/actions/setup-rust
with:
cache-key: pr

- name: Build native modules
run: pnpm run build:native

- name: Library tests
run: pnpm turbo test --filter=@truenine/logger --filter=@truenine/md-compiler --filter=@truenine/script-runtime

test-rust:
if: github.event.pull_request.draft == false
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@v6

- uses: ./.github/actions/setup-rust
with:
cache-key: pr

- name: Rust tests (excluding GUI)
run: cargo test --workspace --exclude memory-sync-gui --lib --bins --tests
Loading
Loading