chore(release): add changelog and contract release versioning strategy - #60
Conversation
📝 WalkthroughWalkthroughAdds checksum tooling, a tagged GitHub Actions release pipeline for Rust WASM contracts, and documentation covering SemVer, artifact verification, release metadata, and deployment records. ChangesContract release process
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant GitHub as GitHub Actions
participant Cargo as Cargo build
participant Provenance as Provenance verification
participant Checksums as SHA256SUMS generation
participant Release as GitHub Release
GitHub->>Cargo: Build release WASM contracts
Cargo-->>GitHub: Produce wpi_token.wasm and mock_amm.wasm
GitHub->>Provenance: Verify dependency provenance
GitHub->>Checksums: Generate SHA256SUMS
Checksums-->>GitHub: Return artifact checksums
GitHub->>Release: Upload WASM artifacts and SHA256SUMS
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (1)
.github/workflows/release.yml (1)
43-48: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winReuse the checked-in checksum tool in CI.
This step duplicates the contract list and bypasses
scripts/checksum_artifacts.sh. The two paths can drift, causing the documentedmake checksumoutput and the attachedSHA256SUMSto cover different artifacts. Runmake checksumand upload its generated file instead.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/release.yml around lines 43 - 48, Update the “Generate SHA-256 Checksums” step to invoke the repository’s existing checksum workflow via make checksum instead of directly listing contract files with sha256sum. Ensure the generated SHA256SUMS file is the one subsequently uploaded, preserving consistency with scripts/checksum_artifacts.sh and the documented make target.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/release.yml:
- Line 17: Update the release workflow action references at the checkout,
rust-toolchain, cache, and release steps to full immutable commit SHAs instead
of mutable tags, and configure the repository’s existing dependency-update
mechanism to keep those SHA pins current.
- Around line 25-32: Update the “Cache cargo registry and build artifacts” step
in the release workflow to remove Stellar-contracts-v1/target from the cached
paths while retaining the Cargo registry, Cargo Git directories, and
Cargo.lock-based cache key.
- Around line 3-6: Add an early validation step to the release workflow
triggered by the push tag pattern, before compilation or release creation, that
accepts only tags matching the documented VMINOR.MAJOR.PATCH format and rejects
values such as v1, vlatest, and v-not-a-version. Keep valid version-tag releases
flowing through the existing build and release jobs.
- Around line 8-9: Restrict contents: write access to the final
action-gh-release publishing step instead of the entire release job. Update
actions/checkout@v4 to disable persisted credentials, keep build, provenance,
and checksum steps read-only, and isolate the publish operation in a last-only
step or job with the write-scoped token.
In `@CHANGELOG.md`:
- Around line 8-10: Update the changelog entries so 0.1.0 remains under
Unreleased and is not presented with a release date until its tag and GitHub
Release are published; move or relabel the 0.1.0 heading accordingly while
preserving its entries.
In `@docs/release-management.md`:
- Around line 129-165: Update the outer Markdown code fence surrounding the
release template in the release-management documentation to use four backticks,
while keeping the inner ```text checksum fence unchanged. Ensure the outer fence
closes with the matching four-backtick delimiter so the nested example renders
correctly.
- Around line 113-116: Update the artifact verification instructions to derive
the checksum from
Stellar-contracts-v1/target/wasm32-unknown-unknown/release/SHA256SUMS produced
by the checked-out rust-toolchain.toml toolchain, rather than a manually copied
release value. Replace the release template’s hard-coded rustc version with the
compiler-version placeholder generated by make checksum or CI metadata.
In `@scripts/checksum_artifacts.sh`:
- Around line 49-52: Update the Git metadata lookup around GIT_REV to run both
rev-parse checks against REPO_ROOT using Git’s -C option, ensuring the commit is
resolved from the release tree rather than the caller’s working directory while
preserving the unknown fallback.
In `@Stellar-contracts-v1/README.md`:
- Around line 54-56: Update the release steps in the README so verified WASM
binaries are deployed before contract IDs are recorded. Revise the deployment
step to deploy the binaries, then add or reorder the contract-ID step to record
the resulting IDs in the release notes, matching the sequence in
docs/release-management.md.
---
Nitpick comments:
In @.github/workflows/release.yml:
- Around line 43-48: Update the “Generate SHA-256 Checksums” step to invoke the
repository’s existing checksum workflow via make checksum instead of directly
listing contract files with sha256sum. Ensure the generated SHA256SUMS file is
the one subsequently uploaded, preserving consistency with
scripts/checksum_artifacts.sh and the documented make target.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: d4c3ce72-f882-4d17-97c7-064cf379caba
📒 Files selected for processing (7)
.github/workflows/release.ymlCHANGELOG.mdMakefileREADME.mdStellar-contracts-v1/README.mddocs/release-management.mdscripts/checksum_artifacts.sh
| on: | ||
| push: | ||
| tags: | ||
| - 'v*' |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow excerpt =="
sed -n '1,140p' .github/workflows/release.yml
echo
echo "== search docs/schema/semver refs =="
rg -n "MAJOR\.MINOR\.PATCH|SemVer|semantic|tag|release|v[0-9]+\.[0-9]+\.[0-9]+|version" -S .github README.md docs scripts 2>/dev/null || true
echo
echo "== all workflow event triggers =="
if [ -d .github/workflows ]; then
rg -n "^\s*(push|pull_request|schedule|workflow_dispatch|release|workflow_run)\s*:|tags\s*:|branches\s*:|paths\s*:|changes\s*:|tags_filter\|branches_filter" .github/workflows || true
fiRepository: Pi-Defi-world/Wpi
Length of output: 10078
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== docs/release-management.md relevant sections =="
sed -n '1,95p' docs/release-management.md
echo
echo "== package/build version declarations =="
for f in Cargo.toml Cargo.lock README.md docs/release-management.md .github/workflows/release.yml; do
if [ -f "$f" ]; then
echo "--- $f ---"
rg -n 'version\s*=|name\s*=|v[0-9]+\.[0-9]+\.[0-9]+|tag|git tag|release-management|SemVer|semantic' "$f" || true
fi
doneRepository: Pi-Defi-world/Wpi
Length of output: 6042
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import re
import fnmatch
patterns = [
"v*",
"v[0-9]+.[0-9]+.[0-9]+",
"v\\d+\\.\\d+\\.\\d+",
r"r" + 'v[0-9]+.[0-9]+.[0-9]+'
]
tags = ['v0.1.0', 'v1', 'vlatest', 'v-not-a-version', 'v1.2.3-rc.1', 'V0.1.0']
for p in patterns:
print(f"glob pattern {p!r}:")
for t in tags:
print(f" {t}: {fnmatch.fnmatch(t, p)}")
PYRepository: Pi-Defi-world/Wpi
Length of output: 710
Reject unsupported release tags before building.
tags: - 'v*' accepts non-version tags like v1, vlatest, and v-not-a-version, so the release job can create draft releases that don’t follow the documented VMINOR.MAJOR.PATCH policy. Add an early tag validation step before compilation and release creation.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml around lines 3 - 6, Add an early validation
step to the release workflow triggered by the push tag pattern, before
compilation or release creation, that accepts only tags matching the documented
VMINOR.MAJOR.PATCH format and rejects values such as v1, vlatest, and
v-not-a-version. Keep valid version-tag releases flowing through the existing
build and release jobs.
| permissions: | ||
| contents: write |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow files =="
git ls-files .github/workflows | sed -n '1,120p'
echo "== release workflow =="
if [ -f .github/workflows/release.yml ]; then
cat -n .github/workflows/release.yml | sed -n '1,120p'
else
echo "missing .github/workflows/release.yml"
fi
echo "== releases mentions in workflows =="
rg -n "permissions:|contents:|persist-credentials|checkout|cdaction|go-attestation|attest|prove|dependency|build|release|publish|uses:.*checkout|on:" .github/workflows/release.yml .github/workflows -C 2 || trueRepository: Pi-Defi-world/Wpi
Length of output: 14191
🌐 Web query:
actions/checkout persist-credentials default true README
💡 Result:
The persist-credentials input in the actions/checkout GitHub Action determines whether the action configures the authentication token or SSH key with the local git configuration [1][2]. Key details include: - Default Value: The default value for persist-credentials is true [1][2]. - Functionality: When set to true, the authentication token (or SSH key) is persisted in the local git configuration [1][3]. This allows subsequent steps in your workflow to execute authenticated git commands (e.g., git push) without needing to manually configure credentials [1][4]. - Cleanup: The token is removed during the post-job cleanup phase of the action [1][5]. - Security Note: While some community discussion has occurred regarding changing this default to false to reduce potential security risks [6][7], it remains true as of July 2026. Users who wish to opt out of this behavior can explicitly set persist-credentials: false in their workflow configuration [1][3].
Citations:
- 1: https://github.com/actions/checkout?tab=readme-ov-file
- 2: https://github.com/actions/checkout/blob/72f2cec99f417b1a1c5e2e88945068983b7965f9/action.yml
- 3: https://github.com/marketplace/actions/checkout?version=v3.6.0
- 4: https://github.com/actions/checkout/blob/main/README.md
- 5: https://github.com/actions/checkout/tree/v6.0.2?tab=readme-ov-file
- 6: [security] Escalate concerning default
persist-credentials=trueplease actions/checkout#2312 - 7: Change the default value of persist-credentials to false actions/checkout#1687
🌐 Web query:
actions checkout token persisted config file path
💡 Result:
In recent versions of actions/checkout (v6.0.0 and later), the authentication token is no longer persisted directly in the repository's local.git/config file [1][2]. Instead, it is stored in a separate, temporary configuration file located in the directory specified by the RUNNER_TEMP environment variable [3][4]. The action utilizes Git's includeIf.gitdir mechanism to conditionally include these credentials only when performing operations within the repository [4]. When the action runs: 1. It generates a unique filename for the credential configuration in the RUNNER_TEMP directory (e.g., git-credentials-.config) [3]. 2. It then updates the Git configuration to reference this file, typically using an include.path or includeIf entry [3][4]. This change was implemented to improve security by isolating the authentication token from the main Git configuration [4]. The tokens are automatically removed during the post-job cleanup process [5][6]. To opt-out of this behavior, you can set the persist-credentials input to false [5][6].
Citations:
- 1: https://github.com/actions/checkout/tree/v6.0.2?tab=readme-ov-file
- 2: https://github.com/actions/checkout/tree/v6.0.0
- 3: actions/checkout@v5.0.1...v6.0.0
- 4: https://github.com/actions/checkout/pull/2286/files
- 5: https://github.com/actions/checkout?tab=readme-ov-file
- 6: https://github.com/actions/checkout/blob/main/README.md
🌐 Web query:
softprops action-gh-release create release permissions write required
💡 Result:
To use the softprops/action-gh-release GitHub Action, you must configure the GitHub token with the appropriate write permissions to create a release. Required Permissions: By default, the action requires the contents permission to be set to write [1][2]. If you also use the discussion_category_name input to create a discussion for the release, you must additionally grant write access to discussions [1][2]. Example Configuration: You can define these permissions at the workflow or job level: permissions: contents: write If discussions are involved: permissions: contents: write discussions: write Important Considerations: 1. Scope: Specifying permissions in a workflow overrides the default permissions. If you define permissions, any category you omit will be set to none. Ensure that other steps in your job are not broken by this restriction [3]. 2. Repository Settings: Even if the YAML configuration is correct, the repository itself must allow Actions to have write access. Check your repository settings under Actions > General > Workflow permissions and ensure "Read and write permissions" is selected [4][3]. 3. GitHub Token Limitations: If you are triggering your workflow on the release event (e.g., on: { release: { types: [published] } }), the default GITHUB_TOKEN will not trigger subsequent workflows. In such cases, you must use a Personal Access Token (PAT) instead [1][2].
Citations:
- 1: https://github.com/softprops/action-gh-release
- 2: https://github.com/softprops/action-gh-release?tab=readme-ov-file
- 3: https://stackoverflow.com/questions/76362343/creating-a-release-using-github-action-fails-with-http-403
- 4: Getting 403 on this workflow softprops/action-gh-release#366
🌐 Web query:
actions checkout v4 persist-credentials default true README
💡 Result:
In actions/checkout v4, the persist-credentials input defaults to true [1][2]. When set to true (the default), the action configures the Git repository using the provided authentication token (or SSH key) in the local git configuration [1][3]. This allows subsequent steps in your workflow to run authenticated Git commands—such as git push or git pull—without requiring additional authentication setup [1][4]. The token is automatically removed during the post-job cleanup phase [1][3]. If you wish to prevent the action from configuring the local git environment with these credentials, you can explicitly set the input to false in your workflow file [1]: - uses: actions/checkout@v4 with: persist-credentials: false It is worth noting that while the default is true, discussions in the community have occasionally raised security considerations regarding this behavior, with some users recommending explicit opt-out for specific use cases [5]. Always ensure your workflow follows the principle of least privilege for the permissions granted to the GitHub Actions token [1].
Citations:
- 1: https://github.com/actions/checkout/blob/v4/README.md
- 2: https://github.com/actions/checkout/blob/v4/action.yml
- 3: https://github.com/actions/checkout/?tab=readme-ov-file
- 4: https://github.com/marketplace/actions/checkout
- 5: [security] Escalate concerning default
persist-credentials=trueplease actions/checkout#2312
Limit the release token to the publish step.
contents: write is granted to the entire release job. actions/checkout@v4 persists credentials by default before the build, dependency provenance, and checksum steps run, so a compromised later step could reuse the token before action-gh-release publishes the release. Disable credential persistence and split the read-only build/provenance steps from a last-only release step that enables the write-scoped release job token.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml around lines 8 - 9, Restrict contents: write
access to the final action-gh-release publishing step instead of the entire
release job. Update actions/checkout@v4 to disable persisted credentials, keep
build, provenance, and checksum steps read-only, and isolate the publish
operation in a last-only step or job with the write-scoped token.
Source: Linters/SAST tools
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout source code | ||
| uses: actions/checkout@v4 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== release workflow =="
cat -n .github/workflows/release.yml | sed -n '1,140p'
echo
echo "== workflow files with contents write =="
python3 - <<'PY'
import subprocess, pathlib, re
for p in sorted(pathlib.Path('.github/workflows').glob('*.yml')) + sorted(pathlib.Path('.github/workflows').glob('*.yaml')):
s=p.read_text()
if 'contents: write' in s:
uses=[]
for i,line in enumerate(s.splitlines(),1):
m=re.search(r'uses:\s*([^@\s]+)@([^\s#\n]+)', line)
if m: uses.append((i,m.group(1), m.group(2)))
print(f"--- {p} ---")
print("contents: write present")
print("actions:")
for item in uses: print(" {}: {}@{}".format(*item))
PYRepository: Pi-Defi-world/Wpi
Length of output: 2641
Pin release-critical actions to immutable commit SHAs.
.github/workflows/release.yml runs with contents: write, but lines 17, 20, 26, and 51 pin mutable references (actions/checkout@v4, dtolnay/rust-toolchain@stable, actions/cache@v4, softprops/action-gh-release@v2). Pin each action to a full commit SHA and keep the pins updated through an automated dependency-update process.
🧰 Tools
🪛 zizmor (1.26.1)
[warning] 16-17: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml at line 17, Update the release workflow action
references at the checkout, rust-toolchain, cache, and release steps to full
immutable commit SHAs instead of mutable tags, and configure the repository’s
existing dependency-update mechanism to keep those SHA pins current.
| - name: Cache cargo registry and build artifacts | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: | | ||
| ~/.cargo/registry | ||
| ~/.cargo/git | ||
| Stellar-contracts-v1/target | ||
| key: ${{ runner.os }}-cargo-release-${{ hashFiles('Stellar-contracts-v1/Cargo.lock') }} |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow file =="
if [ -f .github/workflows/release.yml ]; then
cat -n .github/workflows/release.yml
else
echo "missing .github/workflows/release.yml"
fi
echo
echo "== changed files around release workflow =="
git diff -- .github/workflows/release.yml 2>/dev/null || true
git diff --stat -- .github/workflows/release.yml 2>/dev/null || trueRepository: Pi-Defi-world/Wpi
Length of output: 2448
🌐 Web query:
actions/cache v4 security cache poisoning action cache keys path target untrusted input documentation
💡 Result:
Cache poisoning in GitHub Actions, particularly when using actions/cache, occurs when an attacker injects malicious content into the repository's cache [1][2]. If a later, more privileged workflow (such as a release or deployment pipeline) restores and uses this poisoned cache, it can lead to arbitrary code execution, exfiltration of production secrets, or the compromise of published artifacts [3][4][5]. As of June 2026, GitHub has implemented a significant security mitigation: the Actions service now issues read-only cache tokens for workflow events that can be triggered without write permissions (e.g., certain types of pull request triggers) [6]. This restricts these untrusted workflows from overwriting caches associated with the default branch, closing a common privilege-escalation path [6]. To further mitigate cache poisoning risks, follow these best practices: 1. Use Read-Only Caching: For workflows triggered by untrusted sources, such as pull requests, consider using only cache restoration or ensuring the workflow is configured to avoid write access to sensitive cache keys [6][7]. 2. Segment Cache Keys: Use distinct naming conventions for cache keys based on the trust level or trigger type (e.g., prefixing keys with pr- vs. prod-) to prevent cross-trigger cache collisions [2][5][8]. 3. Minimize Caching in Privileged Workflows: Avoid using caching in highly sensitive workflows, such as those that publish releases or deploy to production, especially if those workflows are susceptible to restoring caches created by untrusted code [9][4]. 4. Validate Restored Content: For critical pipelines, consider hashing the restored cache contents and verifying them against an expected value to detect tampering [8]. 5. Monitor and Audit: Regularly review workflow configurations for permissive cache usage, especially in workflows triggered by pull_request_target or workflow_run, which operate with higher privileges [2][4][5]. Users are encouraged to use actions/cache v4, which is integrated with modern cache service APIs [10][11]. When security issues are identified, they should be reported according to the repository's security policies [10][11].
Citations:
- 1: https://codeql.github.com/codeql-query-help/actions/actions-cache-poisoning-direct-cache/
- 2: https://cloud.hacktricks.wiki/en/pentesting-ci-cd/github-security/abusing-github-actions/gh-actions-cache-poisoning.html
- 3: https://pipebreach.com/posts/cache-poisoning-ci-cd-/
- 4: https://cheatsheetseries.owasp.org/cheatsheets/GitHub_Actions_Security_Cheat_Sheet.html
- 5: https://actsense.dev/vulnerabilities/cache_poisoning/
- 6: https://github.blog/changelog/2026-06-26-read-only-actions-cache-for-untrusted-triggers/
- 7: [CI] Add cache-poisoning mitigations for actions/cache apache/arrow#49730
- 8: https://safeguard.sh/resources/blog/github-actions-cache-poisoning-attack-class-2025
- 9: https://docs.openrewrite.org/recipes/github/security/cachepoisoning
- 10: https://github.com/actions/cache/
- 11: https://github.com/actions/cache/tree/v4
Don’t cache release target artifacts in a mutable cache.
The workflow caches Stellar-contracts-v1/target only with a Cargo.lock hash and then publishes release WASM/checksums from that tree. Keep the lockfile cache, but remove the target path from the release job so release artifacts cannot be affected by a poisoned cache restore.
🧰 Tools
🪛 zizmor (1.26.1)
[error] 26-26: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): enables caching by default
(cache-poisoning)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml around lines 25 - 32, Update the “Cache cargo
registry and build artifacts” step in the release workflow to remove
Stellar-contracts-v1/target from the cached paths while retaining the Cargo
registry, Cargo Git directories, and Cargo.lock-based cache key.
Source: Linters/SAST tools
| ## [Unreleased] | ||
|
|
||
| ## [0.1.0] - 2026-07-28 |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
Do not mark 0.1.0 as released before its tag exists.
This PR does not create the first GitHub Release, but Line 10 presents 0.1.0 as an issued release. Keep these entries under Unreleased until the tag/release is actually published, then add the release date.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@CHANGELOG.md` around lines 8 - 10, Update the changelog entries so 0.1.0
remains under Unreleased and is not presented with a release date until its tag
and GitHub Release are published; move or relabel the 0.1.0 heading accordingly
while preserving its entries.
| 2. Build the contracts using the identical toolchain specified in the release notes: | ||
| ```bash | ||
| make build | ||
| ``` |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Files:"
git ls-files | sed -n '1,200p'
echo
echo "Docs release-management around lines:"
if [ -f docs/release-management.md ]; then
nl -ba docs/release-management.md | sed -n '1,175p'
else
echo "docs/release-management.md not found"
fi
echo
echo "Toolchain-related files and version strings:"
for f in rust-toolchain rust-toolchain.toml toolchain.toml .tool-versions .rustup-toolchain Cargo.toml Makefile Makefile.most makefile; do
if [ -e "$f" ]; then
echo "--- $f ---"
sed -n '1,160p' "$f" | nl -ba
fi
done
echo
echo "Search for CI toolchain/rust 1.88/release template references:"
rg -n "1\.88|rustc|rust-toolchain|make build|rustup|toolchain|Release template|release notes" -S . --glob '!target/**' --glob '!node_modules/**' --glob '!dist/**' | sed -n '1,240p'Repository: Pi-Defi-world/Wpi
Length of output: 17810
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "release-management.md lines 1-180:"
awk '{printf "%6d\t%s\n", NR, $0}' docs/release-management.md | sed -n '1,180p'
echo
echo "Toolchain files:"
for f in rust-toolchain rust-toolchain.toml toolchain.toml .tool-versions .rustup-toolchain; do
if [ -e "$f" ]; then
echo "--- $f ---"
awk '{printf "%6d\t%s\n", NR, $0}' "$f"
fi
done
echo
echo "CI workflow Rust/toolchain references:"
awk '{printf "%6d\t%s\n", NR, $0}' .github/workflows/ci.yml .github/workflows/release.yml | rg -n -i 'rust|toolchain|cargo|soroban|release|make build|1\.88|2026-07-28|rustc' -C 3 || true
echo
echo "Rust toolchain/version references outside target:"
rg -n -i 'rustc\s+1\.88|2026-07-28|1\.88\.0|rust-toolchain|toolchain\.toml|cargo-ndk|soroban-cli|soroban-wit|make build|cargo build' -S --glob '!target/**' --glob '!node_modules/**' --glob '!dist/**' . | sed -n '1,260p'Repository: Pi-Defi-world/Wpi
Length of output: 147
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Release-management docs line count:\n'
wc -l docs/release-management.md || true
printf '\nRelease-management docs lines 1-180:\n'
awk '{printf "%6d\t%s\n", NR, $0}' docs/release-management.md | sed -n '1,180p' || true
printf '\nToolchain files:\n'
for f in rust-toolchain rust-toolchain.toml toolchain.toml .tool-versions .rustup-toolchain; do
if [ -e "$f" ]; then
echo "--- $f ---"
awk '{printf "%6d\t%s\n", NR, $0}' "$f"
fi
done
printf '\nCI workflow snippets around Rust/toolchain/build/release references:\n'
for wf in .github/workflows/ci.yml .github/workflows/release.yml; do
if [ -f "$wf" ]; then
echo "--- $wf ---"
rg -n -i 'rust|toolchain|cargo build|make build|release|rustc|1\.88|2026-07-28|soroban' -C 4 "$wf" || true
fi
done
printf '\nRust/version/toolchain references outside target/build output:\n'
rg -n -i 'rustc\s+1\.88|2026-07-28|1\.88\.0|rust-toolchain|toolchain\.toml|make build|cargo build|soroban-cli|soroban-wit' -S \
--glob '!target/**' --glob '!node_modules/**' --glob '!dist/**' --glob '!**/*.lock' . | sed -n '1,260p' || trueRepository: Pi-Defi-world/Wpi
Length of output: 147
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "release-management.md first 160 lines:"
sed -n '1,160p' docs/release-management.md
echo
echo "toolchain files:"
for f in rust-toolchain rust-toolchain.toml toolchain.toml .tool-versions .rustup-toolchain; do
[ -e "$f" ] && { echo "--- $f ---"; sed -n '1,120p' "$f"; }
done
echo
echo "Release-management Rust/toolchain/build occurrences:"
rg -n -i 'rustc|1\.88|2026-07-28|rust-toolchain|make build|cargo build|release notes|toolchain' docs/release-management.md || true
echo
echo "CI Rust/toolchain/build occurrences:"
rg -n -i 'rust|toolchain|cargo build|make build|release|rustc|1\.88|2026-07-28' \
.github/workflows --glob '*.yml' --glob '*.yaml' || trueRepository: Pi-Defi-world/Wpi
Length of output: 147
🏁 Script executed:
#!/bin/bash
set -uo pipefail
printf 'release-management.txt lines 110-120:\n'
head -n 120 docs/release-management.md | tail -n 18
printf '\nToolchain file if present:\n'
[ -f Stellar-contracts-v1/rust-toolchain.toml ] && sed -n '1,80p' Stellar-contracts-v1/rust-toolchain.toml
printf '\nRelevant release-management occurrences:\n'
rg -n 'Rust|rustc|1\.88|2026-07-28|rust-toolchain|make build|cargo build|Release template|release notes|toolchain' docs/release-management.md || trueRepository: Pi-Defi-world/Wpi
Length of output: 1307
🏁 Script executed:
#!/bin/bash
set -u
printf 'docs/release-management.md lines 60-150:\n'
sed -n '60,150p' docs/release-management.md
printf '\nMakefile build/checksum entries:\n'
rg -n '^(build|checksum|release|contracts|target|artifact)|build:|checksum:' Makefile | sed -n '1,200p' || true
printf '\nWorkflow Rust/toolchain/build/release entries:\n'
rg -n -i 'rust|toolchain|cargo build|make build|release|rustc|1\.88|2026-07-28' .github/workflows --glob '*.yml' --glob '*.yaml' || trueRepository: Pi-Defi-world/Wpi
Length of output: 5939
Bind artifact verification to rust-toolchain.toml, not a hand-filled release copy.
Stellar-contracts-v1/rust-toolchain.toml already pins channel = "1.88.0", so the independent verification step should show that the checksum must come from Stellar-contracts-v1/target/wasm32-unknown-unknown/release/SHA256SUMS generated under the checked-out toolchain. Similarly, the release template should use a generated compiler-version placeholder from make checksum/CI metadata instead of hard-coding rustc 1.88.0 (2026-07-28).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/release-management.md` around lines 113 - 116, Update the artifact
verification instructions to derive the checksum from
Stellar-contracts-v1/target/wasm32-unknown-unknown/release/SHA256SUMS produced
by the checked-out rust-toolchain.toml toolchain, rather than a manually copied
release value. Replace the release template’s hard-coded rustc version with the
compiler-version placeholder generated by make checksum or CI metadata.
| ```markdown | ||
| # Release v[VERSION] ([DATE]) | ||
|
|
||
| This release introduces [Brief summary of the changes in this version]. | ||
|
|
||
| ## Supported Networks | ||
| - Testnet: YES | ||
| - Mainnet: [NO / YES] | ||
|
|
||
| ## Included Contracts | ||
| - `wpi-token` (v[VERSION]) | ||
| - `mock-amm` (v[VERSION]) | ||
|
|
||
| ## Verification Metadata | ||
| - **Compiler Version**: `rustc 1.88.0 (2026-07-28)` | ||
| - **Build Target**: `wasm32-unknown-unknown` | ||
| - **Source Revision**: `[COMMIT_SHA]` | ||
|
|
||
| ### SHA-256 Checksums | ||
| ```text | ||
| [SHA-256-HASH] wpi_token.wasm | ||
| [SHA-256-HASH] mock_amm.wasm | ||
| ``` | ||
|
|
||
| ## Deployment Info | ||
| - **Testnet Contract IDs**: | ||
| - `wpi_token`: `[CONTRACT_ID_TESTNET]` | ||
| - `mock_amm`: `[CONTRACT_ID_TESTNET]` | ||
| - **Mainnet Contract IDs**: | ||
| - `wpi_token`: `[CONTRACT_ID_MAINNET]` | ||
|
|
||
| ## Upgrade Notes | ||
| - [Upgrade instructions if applicable, e.g. state migrations or pause requirements] | ||
|
|
||
| ## Known Limitations | ||
| - [Any outstanding issues or limitations] | ||
| ``` |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Fix the nested Markdown fences in the release template.
The inner ```text fence closes the outer ```markdown block, leaving the template incorrectly rendered. Use four backticks for the outer fence or indent the nested examples.
Proposed fix
-```markdown
+````markdown
...
-```
+````🧰 Tools
🪛 markdownlint-cli2 (0.23.0)
[warning] 165-165: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/release-management.md` around lines 129 - 165, Update the outer Markdown
code fence surrounding the release template in the release-management
documentation to use four backticks, while keeping the inner ```text checksum
fence unchanged. Ensure the outer fence closes with the matching four-backtick
delimiter so the nested example renders correctly.
Source: Linters/SAST tools
| GIT_REV="unknown" | ||
| if command -v git &>/dev/null && git rev-parse --is-inside-work-tree &>/dev/null; then | ||
| GIT_REV=$(git rev-parse HEAD) | ||
| fi |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== files =="
git ls-files | rg '(^|/)checksum_artifacts\.sh$|scripts/'
echo "== checksum_artifacts outline =="
if [ -f scripts/checksum_artifacts.sh ]; then
wc -l scripts/checksum_artifacts.sh
ast-grep outline scripts/checksum_artifacts.sh || true
echo "== relevant contents =="
cat -n scripts/checksum_artifacts.sh
fi
echo "== git usages in file =="
if [ -f scripts/checksum_artifacts.sh ]; then
rg -n '\bgit\b|GIT_REV|REPO_ROOT|source revision|Source Revision' scripts/checksum_artifacts.sh
fi
echo "== git behavior probe if available =="
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
mkdir -p "$tmp/sub"
git init -q "$tmp/repo"
printf 'example\n' > "$tmp/repo/README"
git -C "$tmp/repo" add -A
git -C "$tmp/repo" commit -qm init
git -C "$tmp/repo" tag v1.0
if command -v sh >/dev/null && command -v git >/dev/null; then
REPO_ROOT="$tmp/repo"
echo "current dir outside repo: $(pwd)"
if command -v git &>/dev/null && git rev-parse --is-inside-work-tree &>/dev/null; then
GIT_REV=$(git rev-parse HEAD)
else
GIT_REV="unknown"
fi
echo "probe_without_C GIT_REV=$GIT_REV"
if command -v git &>/dev/null && git -C "$REPO_ROOT" rev-parse --is-inside-work-tree &>/dev/null; then
GIT_REV_WITH_C=$(git -C "$REPO_ROOT" rev-parse HEAD)
else
GIT_REV_WITH_C="unknown"
fi
echo "probe_with_C GIT_REV=$GIT_REV_WITH_C"
cd "$tmp/sub"
if command -v git &>/dev/null && git rev-parse --is-inside-work-tree &>/dev/null; then
GIT_REV=$(git rev-parse HEAD)
else
GIT_REV="unknown"
fi
echo "current dir sub outside repo: $(pwd)"
echo "probe_without_C_inside_subdir GIT_REV=$GIT_REV"
fiRepository: Pi-Defi-world/Wpi
Length of output: 3872
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== git availability =="
command -v git || true
echo "== local git probe =="
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
REPO="$TMP/repo"
mkdir -p "$REPO/stub" "$REPO/subdir"
git init -q "$REPO"
git -C "$REPO" config user.email "probe@example.com"
git -C "$REPO" config user.name "Probe"
printf 'example\n' > "$REPO/README"
git -C "$REPO" add -A
git -C "$REPO" commit -qm init
git -C "$REPO" tag v1.0
cd "$TMP/subdir"
source <(sed -n '1,12p' scripts/checksum_artifacts.sh)
printf 'source-repo-relative-dir git-resolver GIT_REV="%s"\n' "$GIT_REV"
cd "$SCRIPT_DIR/../scripts"
source <(sed -n '1,12p' scripts/checksum_artifacts.sh)
printf 'source-scripts-dir git-resolver GIT_REV="%s"\n' "$GIT_REV"Repository: Pi-Defi-world/Wpi
Length of output: 333
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== local git behavior probe (shell, not script sourcing) =="
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
REPO="$TMP/repo"
mkdir -p "$REPO/subdir"
git init -q "$REPO"
git -C "$REPO" config user.email "probe@example.com"
git -C "$REPO" config user.name "Probe"
printf 'example\n' > "$REPO/README"
git -C "$REPO" add -A
git -C "$REPO" commit -qm init
OUTSIDE_REV="unknown"
if command -v git &>/dev/null && git rev-parse --is-inside-work-tree &>/dev/null; then
OUTSIDE_REV="$(git rev-parse HEAD)"
fi
echo "current_dir_outside_repo_rev=\"$OUTSIDE_REV\""
cd "$REPO/subdir"
REV_IN_SUBDIR="unknown"
if command -v git &>/dev/null && git rev-parse --is-inside-work-tree &>/dev/null; then
REV_IN_SUBDIR="$(git rev-parse HEAD 2>/dev/null || true)"
fi
echo "current_dir_inside_subdir_rev=\"$REV_IN_SUBDIR\""
REV_WITH_C="unknown"
if command -v git &>/dev/null && git -C "$REPO" rev-parse --is-inside-work-tree &>/dev/null; then
REV_WITH_C="$(git -C "$REPO" rev-parse HEAD)"
fi
echo "git_-C_repo_rev=\"$REV_WITH_C\""Repository: Pi-Defi-world/Wpi
Length of output: 419
Resolve Git metadata from REPO_ROOT.
REPO_ROOT is computed, but git rev-parse still depends on the caller’s working directory. Run Git with -C "$REPO_ROOT" so the generated checksum metadata records the commit for this release tree and cannot silently fallback to unknown.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/checksum_artifacts.sh` around lines 49 - 52, Update the Git metadata
lookup around GIT_REV to run both rev-parse checks against REPO_ROOT using Git’s
-C option, ensuring the commit is resolved from the release tree rather than the
caller’s working directory while preserving the unknown fallback.
| 3. Commit and push a git release tag (`vMAJOR.MINOR.PATCH`). | ||
| 4. Rely on automated CI to generate draft GitHub Releases with attached WASM artifacts. | ||
| 5. Deploy verified WASM binaries using contract IDs recorded in the release. |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Record contract IDs after deployment, not before.
Contract IDs are produced by deployment, so they cannot be used to deploy the WASM. Align this step with docs/release-management.md: deploy the verified binaries, then record the resulting IDs in the release notes.
Proposed wording
-5. Deploy verified WASM binaries using contract IDs recorded in the release.
+5. Deploy the verified WASM binaries from the release.
+6. Record the resulting contract IDs in the release notes.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 3. Commit and push a git release tag (`vMAJOR.MINOR.PATCH`). | |
| 4. Rely on automated CI to generate draft GitHub Releases with attached WASM artifacts. | |
| 5. Deploy verified WASM binaries using contract IDs recorded in the release. | |
| 3. Commit and push a git release tag (`vMAJOR.MINOR.PATCH`). | |
| 4. Rely on automated CI to generate draft GitHub Releases with attached WASM artifacts. | |
| 5. Deploy the verified WASM binaries from the release. | |
| 6. Record the resulting contract IDs in the release notes. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Stellar-contracts-v1/README.md` around lines 54 - 56, Update the release
steps in the README so verified WASM binaries are deployed before contract IDs
are recorded. Revise the deployment step to deploy the binaries, then add or
reorder the contract-ID step to record the resulting IDs in the release notes,
matching the sequence in docs/release-management.md.
Summary
This PR introduces a standardized release and versioning workflow for the WPI smart contracts by adding a project changelog, documenting semantic versioning practices, and defining a reproducible contract release process.
Closes #31
Overview
Currently all contract crates remain at version
0.1.0, there is no centralized changelog, and deployed WASM artifacts cannot easily be traced back to a specific repository state.This PR establishes a release strategy that improves deployment traceability, reproducibility, and long-term maintenance.
Changes
CHANGELOG
Added a root-level
CHANGELOG.mdfollowing the Keep a Changelog format.The changelog includes:
Prepared an initial release entry for the current contract version.
Semantic Versioning
Documented Semantic Versioning (SemVer) guidelines for contract crates.
Release policy now defines:
This provides a predictable versioning strategy across future releases.
Release Workflow
Documented the recommended deployment workflow for both testnet and mainnet.
Each release should include:
.wasmartifactsThis enables reproducible deployments and easier auditing.
WASM Artifact Verification
Added guidance for generating and publishing artifact hashes.
Each release records:
This allows deployed binaries to be independently verified against source code.
Deployment Documentation
Updated deployment documentation to include the release lifecycle:
GitHub Release Strategy
Documented a standard release template including:
This creates a consistent release process for future deployments.
Files Added
Files Updated
Validation
Verified:
Acceptance Criteria
Notes
Creating the first GitHub Release, attaching compiled
.wasmbinaries, and publishing release assets must be performed by a maintainer with repository release permissions after this PR is merged.This PR prepares the repository and documentation for that release process but does not create the GitHub release itself.
Result
This PR establishes a standardized release management process for the WPI contracts, improving reproducibility, deployment traceability, artifact verification, and long-term maintenance while providing a clear versioning strategy for future protocol evolution.
Summary by CodeRabbit
New Features
Documentation