Skip to content
Open
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
88 changes: 0 additions & 88 deletions .github/workflows/artifacts-publish.yml

This file was deleted.

48 changes: 48 additions & 0 deletions .github/workflows/check-artifacts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Generated artifacts in sync

# Validates that auto-generated content committed to the repo is in sync
# with its sources:
# npm-artifacts/src/abi.ts ← extracted ABIs (shipped via @aragon/staged-proposal-processor-plugin-artifacts)
#
# If a PR changes a contract but forgets to regenerate the ABI, CI fails with
# a clear message telling the contributor what to run.

on:
push:
branches:
- main
- release-v*
pull_request:
paths:
- 'src/**'
- 'foundry.toml'
- 'remappings.txt'
- 'npm-artifacts/prepare-abi.sh'
- 'npm-artifacts/src/abi.ts'

jobs:
check:
name: Generated artifacts
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
persist-credentials: false

- uses: foundry-rs/foundry-toolchain@v1
with:
version: stable
- uses: extractions/setup-just@v2
- run: sudo apt-get update && sudo apt-get install -y jq

- name: Verify ABI is in sync with contracts
run: |
(cd npm-artifacts && just abi)
if ! git diff --exit-code -- npm-artifacts/src/abi.ts; then
echo "::error::npm-artifacts/src/abi.ts is out of date."
echo "::error::Run 'just abi' from npm-artifacts/ locally and commit the diff."
exit 1
fi
68 changes: 68 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Release

# Releases @aragon/staged-proposal-processor-plugin-artifacts.
#
# Flow:
# 1. A PR bumps `npm-artifacts/package.json#version`.
# 2. On merge to main or any release-v* branch, this workflow runs.
# 3. If the version is new (no tag `vX.Y.Z` yet), it builds, tags, pushes the
# tag, and publishes to NPM. Otherwise it exits cleanly.

on:
push:
branches:
- main
- release-v*
paths: ['npm-artifacts/package.json']

permissions:
contents: write # to push the tag

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-tags: true # need existing tags for the version-already-released check
submodules: recursive
persist-credentials: true # needed to push the tag

- uses: foundry-rs/foundry-toolchain@v1
with:
version: stable
- uses: extractions/setup-just@v2
- uses: oven-sh/setup-bun@v2
- run: sudo apt-get update && sudo apt-get install -y jq

- name: Resolve version + skip flag
id: meta
run: |
set -euo pipefail
version=$(jq -r '.version' npm-artifacts/package.json)
[[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-z0-9]+(\.[0-9]+)?)?$ ]] || { echo "::error::Bad semver in package.json: $version"; exit 1; }
tag="v$version"

if git rev-parse "$tag" >/dev/null 2>&1; then
echo "Tag $tag already exists — version is unchanged or was previously released. Skipping."
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "skip=false" >> "$GITHUB_OUTPUT"
echo "tag=$tag" >> "$GITHUB_OUTPUT"

- name: Build
if: steps.meta.outputs.skip != 'true'
run: cd npm-artifacts && just build

- name: Tag
if: steps.meta.outputs.skip != 'true'
run: |
git tag "${{ steps.meta.outputs.tag }}"
git push origin "${{ steps.meta.outputs.tag }}"

- name: Publish to NPM
if: steps.meta.outputs.skip != 'true'
env:
NPM_CONFIG_TOKEN: ${{ secrets.NPM_TOKEN }}
run: cd npm-artifacts && bun publish --access public
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ docs-gen/bun.lock
.DS_Store
src/.DS_Store

npm-artifacts/src/abi.ts
npm-artifacts/dist
npm-artifacts/node_modules
report/
lcov.info
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## v1.2

### Changed

- Recompiled against an amended `osx-commons` `RuledCondition._evalLogic`. The IF_ELSE starting rule now evaluates with `_where`/`_who` in the same order as the surrounding `_evalRule` call. No setup interface change.

### Added

- SPP-level regression tests for `SPPRuleCondition.isGranted` covering an asymmetric IF_ELSE predicate (success/failure routing and a swapped-args caller path).
- Unit and fork tests for `prepareUpdate`.
- `script/NewVersion.s.sol` now also prints the management DAO multisig `createProposal` calldata wrapping the `createVersion` action — including the pinned `PROPOSAL_METADATA` URI as the proposal metadata — so a multisig member can submit it directly.
- `script/Deploy.s.sol` now publishes `PlaceholderSetup` builds for builds 1..VERSION_BUILD-1 on a fresh repo before publishing the real `SPPSetup` build, keeping on-chain build numbers aligned across networks.
- `PROPOSAL_METADATA` and `PLACEHOLDER_BUILD_METADATA` constants in `PluginSettings.sol`, and `script/new-version-proposal-metadata.json` as the v1.2 proposal metadata source.

## v1.1

### Added
Expand Down
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,40 @@ forge build
```shell
just test # unit tests
just test-fork # fork tests (requires RPC_URL)
just validate-upgrade SPPStorageV1 StagedProposalProcessor # storage layout check
just check-upgrade SPPStorageV1 StagedProposalProcessor # storage layout compatibility check
```

## Deploy

```shell
just deploy # initial deployment (creates plugin repo, publishes v1)
just new-version # deploy new setup + print DAO proposal calldata
just new-version # deploy new setup + print management DAO multisig proposal calldata
```

Set `SPP_ENS_SUBDOMAIN=spp` in `.env` for production deployments. Omitting it generates a unique name (`spp-<timestamp>`), which is useful for testing.

### Publishing a new build

1. Bump `VERSION_BUILD` in `src/utils/PluginSettings.sol`.
2. Edit `src/build-metadata.json` and `script/new-version-proposal-metadata.json` for this build (and `src/release-metadata.json` if shipping a new release).
3. Pin and update the matching constants in `PluginSettings.sol`:
```shell
just ipfs-pin src/build-metadata.json # → BUILD_METADATA
just ipfs-pin script/new-version-proposal-metadata.json # → PROPOSAL_METADATA
just ipfs-pin src/release-metadata.json # → RELEASE_METADATA (only on a new release)
```
4. Run `just new-version`. The script deploys the new `SPPSetup` and prints two calldata blobs:
- the inner `createVersion` action (`to = SPP_PLUGIN_REPO_ADDRESS`), and
- the outer management DAO multisig `createProposal` call (`to = MANAGEMENT_DAO_MULTISIG_ADDRESS`) including the pinned `PROPOSAL_METADATA` URI — submit it from any listed multisig member to publish the version.

On a brand-new network, `just deploy` automatically publishes `PlaceholderSetup` builds for any build numbers below `VERSION_BUILD` before publishing the real one, so build numbers stay aligned with networks where prior builds shipped.

### Upgrading existing installations

Publishing a new build does not upgrade installed plugins. Each DAO running an older build needs a proposal that calls `psp.applyUpdate(...)`.

Version 1.2 is published with the same `IMPLEMENTATION` as 1.1 (bytecode is identical), so `applyUpdate` skips the proxy upgrade — no `UPGRADE_PLUGIN_PERMISSION` grant/revoke bracket is required.

### Deployment Checklist

- [ ] I have cloned the official repository on my computer and I have checked out the `main` branch
Expand All @@ -73,6 +95,7 @@ Set `SPP_ENS_SUBDOMAIN=spp` in `.env` for production deployments. Omitting it ge
- [ ] I have created a new burner wallet with `cast wallet new` and used its private key as `DEPLOYER_KEY`
- [ ] I am the only person of the ceremony that will operate the deployment wallet
- [ ] All the tests run clean (`just test`)
- [ ] `just check-upgrade OldContract NewContract` reports the storage layout check passed
- My computer:
- [ ] Is running in a safe location and using a trusted network
- [ ] It exposes no services or ports
Expand Down
10 changes: 8 additions & 2 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,22 @@ docs:
cd docs-gen && bun install && bash prepare-docs.sh && bun prepare-docs.js

DEPLOY_SCRIPT := "script/Deploy.s.sol:Deploy"
NEW_VERSION_SCRIPT := "script/NewVersion.s.sol:NewVersion"

# Dry-run the new-version script (no broadcast) — eyeball the printed multisig calldata
[group('upgrade')]
pre-new-version:
just dry-run {{ NEW_VERSION_SCRIPT }}

# Publish a new SPP plugin version (deploys setup, prints DAO proposal calldata)
[group('upgrade')]
new-version *args:
#!/usr/bin/env bash
set -euo pipefail
source {{ ENV_RESOLVE_LIB }} && env_load_network
source {{ JUST_LIB }} && env_load_network
mkdir -p logs
LOG_FILE="logs/new-version-$NETWORK_NAME-$(date +"%y-%m-%d-%H-%M").log"
just test 2>&1 | tee -a "$LOG_FILE"
just run script/NewVersion.s.sol:NewVersion {{ args }} 2>&1 | tee -a "$LOG_FILE"
just run {{ NEW_VERSION_SCRIPT }} {{ args }} 2>&1 | tee -a "$LOG_FILE"
echo "Logs saved in $LOG_FILE"

Loading
Loading