Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
5d00884
fix: fail CLI writes on execution errors (#345)
MuncleUscles Jun 9, 2026
6fadcd7
fix(contracts)!: require consensus acceptance for success, not just t…
MuncleUscles Jun 10, 2026
2100255
ci: keep main forwarded to active dev branch (#348)
MuncleUscles Jun 10, 2026
9ebf9e0
fix(system): propagate command-check and version parse fixes to v0.40…
MuncleUscles Jun 11, 2026
8c898c3
docs: add branching guide (#353)
MuncleUscles Jun 11, 2026
6edfcfa
feat: support fee profiles in contract commands (#355)
MuncleUscles Jun 16, 2026
0e76bce
feat: staking validators discovery (#357)
MuncleUscles Jul 7, 2026
7bcc41e
feat: vesting commands (#358)
MuncleUscles Jul 7, 2026
45a3ce9
chore(deps): update dependency uuid to v11.1.1 [security] (#320)
renovate[bot] Jul 7, 2026
561370f
fix(init): use backend provider id "google" for Gemini (#359)
Tobu8888 Jul 7, 2026
f1f1304
fix(docs-sync): stop overwriting the generated root _meta.json (#352)
acastellana Jul 7, 2026
32a0a42
fix: drop getSlashingAddress from validator-history (#361)
MuncleUscles Jul 7, 2026
185d22b
feat(network): custom network profiles with deployment-file import (#…
MuncleUscles Jul 8, 2026
a4f8a63
fix: make git install build lifecycle robust (#363)
MuncleUscles Jul 8, 2026
841e35e
ci: publish prereleases to npm dist tags (#364)
MuncleUscles Jul 8, 2026
b5dbdb7
Release v0.40.0-rc1 [skip ci]
MuncleUscles Jul 8, 2026
3cd1cac
fix: avoid git dependency in npm prerelease install (#368)
MuncleUscles Jul 8, 2026
3996ab4
Release v0.40.0-rc2 [skip ci]
MuncleUscles Jul 8, 2026
3748358
ci: add npm dist-tag channel workflow (#369)
MuncleUscles Jul 8, 2026
d520311
ci: use npm auth token secret for package operations (#370)
MuncleUscles Jul 8, 2026
6c1b27b
ci: publish prereleases to named npm channels (#371)
MuncleUscles Jul 8, 2026
6f95f82
Release v0.40.0-clarke.1 [skip ci]
MuncleUscles Jul 8, 2026
3396474
ci: remove obsolete npm dist-tag workflow (#372)
MuncleUscles Jul 8, 2026
ab128c0
feat(staking): browser-wallet signing for validator-join and wizard (…
MuncleUscles Jul 9, 2026
f892371
test: make wallet session descriptor tests portable (#373)
MuncleUscles Jul 9, 2026
ffa8ae7
Release v0.40.0-clarke.2 [skip ci]
MuncleUscles Jul 9, 2026
121ab27
test(wallet): cover WalletAction status/disconnect + availableToStake…
MuncleUscles Jul 9, 2026
de8858a
docs(cli): document browser-wallet signing, custom networks, balances…
MuncleUscles Jul 9, 2026
4b26cc6
test(wallet): Tier-2 browser-signing e2e (Playwright + mock provider …
MuncleUscles Jul 9, 2026
3de9a6a
fix(staking): validator-deposit/exit work through the CLI (#382)
MuncleUscles Jul 9, 2026
e55f917
fix(wallet): harden bridge (verify signer, Host check, constant-time …
MuncleUscles Jul 9, 2026
ef47935
feat(staking): non-interactive wizard mode (#384)
MuncleUscles Jul 9, 2026
923475d
fix(cli): read commands honor a live wallet session (connect-once ide…
MuncleUscles Jul 9, 2026
6249e26
feat(staking): wizard guides identity on the vesting funding path (#386)
MuncleUscles Jul 9, 2026
e70b31b
fix(staking): route set-operator/validator-claim/set-identity/trace t…
MuncleUscles Jul 9, 2026
e35a57d
refactor(wallet): route browser-wallet writes through the SDK (#388)
MuncleUscles Jul 10, 2026
8cdcb8a
fix(balances): degrade gracefully when staking is unavailable (#389)
MuncleUscles Jul 10, 2026
f2d9c98
fix(balances): wallet-only view when consensus infra is not deployed …
MuncleUscles Jul 10, 2026
0ce6b1b
fix(account): clear error for password prompts with no TTY (#390)
MuncleUscles Jul 10, 2026
d7e3dcb
Release v0.40.0-clarke.3 [skip ci]
MuncleUscles Jul 10, 2026
74952bd
feat(wallet): EIP-6963 multi-wallet discovery in the browser bridge (…
MuncleUscles Jul 10, 2026
015e6d4
feat(network): --explorer override for custom networks; stop inheriti…
MuncleUscles Jul 10, 2026
dd77d5b
feat(staking): validator eligibility warnings + clean validator-info …
MuncleUscles Jul 10, 2026
054200d
Release v0.40.0-clarke.4 [skip ci]
MuncleUscles Jul 10, 2026
f8829fb
fix: compile deploy scripts in an isolated temp directory (#398)
MuncleUscles Jul 26, 2026
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
107 changes: 107 additions & 0 deletions .github/scripts/validate-branch-policy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/usr/bin/env bash
set -euo pipefail

failed=0

error() {
echo "::error::$*"
failed=1
}

warning() {
echo "::warning::$*"
}

active_branch_file="support/ci/ACTIVE_DEV_BRANCH"
if [[ ! -f "${active_branch_file}" ]]; then
error "${active_branch_file} is required."
active_branch=""
else
active_branch="$(tr -d '[:space:]' < "${active_branch_file}")"
fi

if [[ -z "${active_branch}" ]]; then
error "${active_branch_file} must not be empty."
elif [[ "${active_branch}" == "main" ]]; then
error "${active_branch_file} must point to a dev branch, not main."
elif [[ "${active_branch}" != *-dev ]]; then
warning "${active_branch_file} should normally point to a -dev branch; got ${active_branch}."
fi

release_branch="${active_branch%-dev}"
default_branch="${GITHUB_DEFAULT_BRANCH:-}"
event_name="${GITHUB_EVENT_NAME:-local}"
base_ref="${GITHUB_BASE_REF:-}"
head_ref="${GITHUB_HEAD_REF:-}"
ref_name="${GITHUB_REF_NAME:-}"
actor="${GITHUB_ACTOR:-}"

if [[ -n "${default_branch}" && "${default_branch}" != "main" ]]; then
warning "Repository default branch should be main after branch-policy rollout; currently ${default_branch}."
fi

if [[ -n "${base_ref}" && "${base_ref}" == "main" ]]; then
warning "PR targets main; retarget-main-prs should move it to ${active_branch}."
fi

if [[ -n "${base_ref}" && -n "${active_branch}" ]]; then
if [[ "${base_ref}" == "${release_branch}" && "${head_ref}" != "${active_branch}" && "${ALLOW_DIRECT_RELEASE_PR:-false}" != "true" ]]; then
error "PRs into ${release_branch} must come from ${active_branch}. Merge feature work into ${active_branch}, then promote ${active_branch} -> ${release_branch}."
fi
fi

if [[ "${event_name}" == "push" && "${ref_name}" == "main" ]]; then
case "${actor}" in
github-actions[bot]|ci-core-e2e-runner[bot])
;;
*)
error "main should only move by automation from ${active_branch}; direct push actor was ${actor:-unknown}."
;;
esac
fi

if [[ ! -f ".github/workflows/fast-forward-main.yaml" ]]; then
error ".github/workflows/fast-forward-main.yaml is required."
fi

if [[ ! -f ".github/workflows/retarget-main-prs.yaml" ]]; then
error ".github/workflows/retarget-main-prs.yaml is required."
fi

if [[ -f ".github/workflows/release-from-main.yml" ]]; then
error ".github/workflows/release-from-main.yml is forbidden. Releases must be tag/version-branch driven."
fi

if [[ -f "release.config.js" ]]; then
error "release.config.js is forbidden in versioned tooling branches; semantic-release-on-main must not be restored."
fi

if [[ -f ".github/workflows/release-from-tag.yml" ]]; then
if ! grep -Fq 'v*.*.*' .github/workflows/release-from-tag.yml; then
error "release-from-tag.yml must trigger only from version tags matching v*.*.*."
fi
if ! grep -Fq 'refs/remotes/origin/${version_branch}' .github/workflows/release-from-tag.yml || \
! grep -Fq 'tag_commit' .github/workflows/release-from-tag.yml || \
! grep -Fq 'branch_head' .github/workflows/release-from-tag.yml; then
error "release-from-tag.yml must verify the tag commit is the current matching version branch head."
fi
fi

if [[ -f ".github/workflows/manual-docker-release.yml" ]]; then
if ! grep -Fq 'expected_branch=' .github/workflows/manual-docker-release.yml; then
error "manual-docker-release.yml must derive and enforce the expected version branch from the tag."
fi
if ! grep -Fq './.github/workflows/release-from-tag.yml' .github/workflows/manual-docker-release.yml; then
error "manual-docker-release.yml must delegate image promotion to release-from-tag.yml."
fi
fi

if [[ "${failed}" -ne 0 ]]; then
exit 1
fi

if [[ -n "${base_ref}" ]]; then
echo "Branch policy ok for PR ${head_ref} -> ${base_ref}; active dev branch is ${active_branch}."
else
echo "Branch policy ok for ${event_name} on ${ref_name:-detached ref}; active dev branch is ${active_branch}."
fi
24 changes: 24 additions & 0 deletions .github/workflows/branch-policy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Branch Policy

on:
pull_request:
types: [opened, synchronize, reopened, edited, ready_for_review]
push:
branches:
- "**"
workflow_dispatch:

permissions:
contents: read

jobs:
branch-policy:
name: Validate branch policy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Validate branch policy
env:
GITHUB_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
run: ./.github/scripts/validate-branch-policy.sh
63 changes: 63 additions & 0 deletions .github/workflows/e2e-wallet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Tier-2 browser-wallet signing e2e (Playwright + mock provider on anvil).
#
# INFORMATIONAL / NOT A REQUIRED GATE (initially). This job drives a headless
# chromium against the real bridge page with a viem-backed mock window.ethereum
# that signs+broadcasts to an ephemeral anvil, exercising the full
# connect -> sign -> receipt loop with zero MetaMask. Keep it OFF the required
# status checks in branch protection until it has proven stable across a few
# weeks of PRs, then promote it to required.
#
# Distinct filename from the synced cross-repo e2e.yml (the /run-e2e cucumber
# pipeline) so the two never collide.
name: E2E Wallet (Tier 2)

on:
pull_request:
types: [opened, synchronize, reopened]
push:
branches:
- v0.40
- v0.40-dev

jobs:
e2e-wallet:
name: Browser-wallet e2e (anvil lanes)
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install libsecret runtime
run: sudo apt-get update && sudo apt-get install -y libsecret-1-0

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"

- name: Install dependencies
run: npm ci

- name: Build the project
run: npm run build

- name: Install Foundry (anvil)
uses: foundry-rs/foundry-toolchain@v1

- name: Install Playwright chromium
run: npx playwright install --with-deps chromium

- name: Run Tier-2 e2e (anvil lanes)
run: npm run test:e2e

- name: Upload Playwright report
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: |
playwright-report/
test-results/
retention-days: 7
if-no-files-found: ignore
57 changes: 57 additions & 0 deletions .github/workflows/fast-forward-main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Fast-forward main

# main is the static/default branch for GitHub UX and tools that assume a
# stable default branch. It is not the integration target. On each push to the
# configured active dev branch, fast-forward main to that commit.

on:
push:
branches: ["**"]
workflow_dispatch:

permissions:
contents: write

concurrency:
group: fast-forward-main-${{ github.repository }}
cancel-in-progress: false

defaults:
run:
shell: bash

jobs:
fast-forward:
if: github.ref_type == 'branch'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Fast-forward main to active dev branch
run: |
set -euo pipefail

active_branch="$(tr -d '[:space:]' < support/ci/ACTIVE_DEV_BRANCH)"
if [[ -z "${active_branch}" || "${active_branch}" == "main" ]]; then
echo "::error::support/ci/ACTIVE_DEV_BRANCH must name a non-main dev branch"
exit 1
fi

if [[ "${GITHUB_REF_NAME}" != "${active_branch}" ]]; then
echo "Push was to ${GITHUB_REF_NAME}; active dev branch is ${active_branch}. Nothing to do."
exit 0
fi

if git ls-remote --exit-code --heads origin main >/dev/null 2>&1; then
git fetch origin main
if ! git merge-base --is-ancestor origin/main HEAD; then
echo "::error::main has diverged from ${active_branch}; refusing non-fast-forward update"
exit 1
fi
else
echo "main does not exist yet; creating it at ${GITHUB_SHA}."
fi

git push origin "HEAD:refs/heads/main"
53 changes: 49 additions & 4 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ name: Publish Package to NPM
# workflow fires on the tag push, sanity-checks the tag matches
# package.json, builds, publishes to npm, and creates the GitHub
# Release. It never bumps or tags by itself.
#
# Stable tags such as v0.39.2 publish to npm's latest dist-tag.
# Prerelease tags such as v0.40.0-clarke.1 publish to a matching
# channel dist-tag (clarke) and create a GitHub prerelease.
# Prereleases must never become latest.
on:
workflow_dispatch:
push:
Expand All @@ -32,23 +37,52 @@ jobs:

- run: npm ci

- name: Verify tag matches package.json version
- name: Verify tag and resolve npm dist-tag
id: version
run: |
if [ "${GITHUB_REF_TYPE:-}" != "tag" ]; then
echo "Publish must run from a git tag. Current ref type: ${GITHUB_REF_TYPE:-unknown}" >&2
exit 1
fi

TAG_VERSION="${GITHUB_REF_NAME#v}"
PKG_VERSION="$(node -p "require('./package.json').version")"
if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
echo "Tag ($TAG_VERSION) and package.json ($PKG_VERSION) disagree — refusing to publish." >&2
echo "Re-cut the release via scripts/release.sh so the tag and the committed version match." >&2
exit 1
fi

IS_PRERELEASE=false
NPM_DIST_TAG=latest
if [[ "$TAG_VERSION" == *-* ]]; then
IS_PRERELEASE=true
PRERELEASE_SUFFIX="${TAG_VERSION#*-}"
PRERELEASE_SUFFIX="${PRERELEASE_SUFFIX%%+*}"
NPM_DIST_TAG="${PRERELEASE_SUFFIX%%.*}"

if [ -z "$NPM_DIST_TAG" ] || [ "$NPM_DIST_TAG" = "latest" ]; then
echo "Invalid prerelease npm dist-tag: '$NPM_DIST_TAG'" >&2
exit 1
fi

if [[ "$NPM_DIST_TAG" =~ ^v?[0-9] ]]; then
echo "Invalid prerelease npm dist-tag '$NPM_DIST_TAG': dist-tags must not look like versions." >&2
exit 1
fi
fi

echo "Tag $GITHUB_REF_NAME matches package.json $PKG_VERSION."
echo "npm dist-tag: $NPM_DIST_TAG"
echo "is_prerelease=$IS_PRERELEASE" >> "$GITHUB_OUTPUT"
echo "npm_dist_tag=$NPM_DIST_TAG" >> "$GITHUB_OUTPUT"

- run: npm run build

- name: Publish to npm
run: npm publish --provenance --access public
run: npm publish --provenance --access public --tag "${{ steps.version.outputs.npm_dist_tag }}"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN || secrets.NPM_TOKEN }}

- name: Create GitHub Release
env:
Expand All @@ -62,6 +96,17 @@ jobs:
if [ -z "$NOTES" ]; then
NOTES="Release $GITHUB_REF_NAME"
fi

NOTES="$NOTES

npm install -g genlayer@${{ steps.version.outputs.npm_dist_tag }}"

RELEASE_FLAGS=()
if [ "${{ steps.version.outputs.is_prerelease }}" = "true" ]; then
RELEASE_FLAGS+=(--prerelease)
fi

gh release create "$GITHUB_REF_NAME" \
--title "$GITHUB_REF_NAME" \
--notes "$NOTES"
--notes "$NOTES" \
"${RELEASE_FLAGS[@]}"
53 changes: 53 additions & 0 deletions .github/workflows/retarget-main-prs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Retarget main PRs

# main is a static/default alias of the active dev branch. Contributions should
# target the active dev branch directly; PRs opened against main are retargeted
# automatically so required checks and release-train rules run in the right
# branch context.
#
# pull_request_target is used for the write-scoped token. This workflow never
# checks out or executes PR head code; it reads only trusted base-branch files.

on:
pull_request_target:
types: [opened, reopened, synchronize, edited, ready_for_review]

permissions:
contents: read
pull-requests: write
issues: write

defaults:
run:
shell: bash

jobs:
retarget:
if: github.event.pull_request.base.ref == 'main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.ref }}

- name: Retarget PR to active dev branch
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
set -euo pipefail

active_branch="$(tr -d '[:space:]' < support/ci/ACTIVE_DEV_BRANCH)"
if [[ -z "${active_branch}" || "${active_branch}" == "main" ]]; then
echo "::error::support/ci/ACTIVE_DEV_BRANCH must name a non-main dev branch"
exit 1
fi

gh pr edit "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --base "${active_branch}"

gh pr comment "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --body "$(cat <<EOF
This PR targeted \`main\`, which is only the default/static branch.

I retargeted it to \`${active_branch}\`, the active development branch. Pushes to \`${active_branch}\` automatically fast-forward \`main\`.
EOF
)"
Loading
Loading