This document describes the process for releasing new versions of the Invoice Liquidity Network protocol across three coordinated repositories.
ILN releases require coordinating changes across three repositories:
- ILN-Smart-Contract β Rust/Soroban contracts (deployed to Stellar)
- Invoice-Liquidity-Network β SDK, CLI, indexer, notifications (this repo)
- ILN-Frontend β Next.js dApp
The correct release order is critical: smart contract deployment must complete before SDK updates, and SDK updates must complete before frontend deployment.
This repository contains four release-related workflows. The following diagram shows what triggers each, what they publish, and how they relate:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Release Workflows β
ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Workflow β Trigger / Relationship β
ββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββ€
β coordinate-release β workflow_dispatch (manual) β
β β Orchestrator β does NOT call the other three β
β β via workflow_call. Tags repos, polls CI, β
β β and sends Discord notifications. β
ββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββ€
β release.yml β push to main (changesets) β
β β Opens "Version Packages" PR; merging it β
β β publishes ALL packages via changeset publish. β
β β Independent of coordinate-release.yml. β
ββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββ€
β sdk-release.yml β push of v* tags OR PR touching packages/sdk/ β
β β Publishes @iln/sdk to npm with provenance; β
β β creates GitHub Release. Dry-run on PRs. β
β β Independent of the other three workflows. β
ββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββ€
β scripts-release.yml β push of @iln/scripts@* tags OR PR touching β
β β packages/scripts/ β
β β Publishes @iln/scripts to npm with provenance; β
β β creates GitHub Release. Dry-run on PRs. β
β β Independent of the other three workflows. β
ββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββ
Developer main branch release.yml npm
β β β β
βββ merge PR βββββββ>β β β
β βββ push trigger ββββ>β β
β β βββ detect changesets
β β βββ open "Version β
β β β Packages" PR β
β β<βββββββββββββββββββ β β
β β β β
βββ merge version PR>β β β
β βββ push trigger ββββ>β β
β β βββ changeset publish
β β βββ npm publish ββββ>β
β β βββ attest provenanceβ
Developer v* tag sdk-release.yml npm
β β β β
βββ git push tag βββ>β β β
β βββ push trigger ββββ>β β
β β βββ install + build β
β β βββ test β
β β βββ npm publish ββββ>β
β β βββ GitHub Release β
Maintainer coordinate-release.yml Smart Contract Repo SDK Repo Frontend Repo
β β β β β
βββ dispatch(v1.2.0)ββ>β β β β
β βββ validate version β β β
β βββ tag v1.2.0 βββββββββββ>β β β
β βββ poll CI (β€10 min) ββββββ β β
β βββ update contract IDs ββββββββββββββββββ> β β
β βββ run SDK tests βββββββββββββββββββββββββ>β β
β βββ tag sdk-v1.2.0 ββββββββββββββββββββββββ>β β
β βββ trigger frontend update βββββββββββββββββββββββββββββββ> β
β βββ poll frontend CI ββββββββββββββββββββββββββββββββββββββββ
β βββ tag frontend-v1.2.0 βββββββββββββββββββββββββββββββββββ>β
β βββ Discord notification β β
- No
workflow_calldependencies exist between the four workflows. Each is independently triggered. coordinate-release.ymlis a manual orchestrator β it usesgh apiandgh workflow runto tag repos and trigger CI, but does not invokerelease.yml,sdk-release.yml, orscripts-release.ymlas callable workflows.release.yml(changesets) andsdk-release.yml(tag-based) can both publish@iln/sdkdepending on the release path chosen. This is not a bug β they serve different release strategies (changesets workflow vs. manual tag push). However, teams should pick one strategy to avoid duplicate publishes.scripts-release.ymlexclusively publishes@iln/scriptsand has no overlap with the other workflows.
- Deploy new contract version to Stellar testnet/mainnet
- Tag the contract repository with the version (e.g.,
v1.2.0) - CI verifies deployment and generates new contract IDs
- Update contract IDs in SDK based on new deployment
- Run full SDK test suite
- Tag SDK release with
sdk-v1.2.0 - Publish SDK to npm if applicable
- Update SDK dependency in frontend package.json
- Run frontend CI (build, linting, tests)
- Tag frontend release with
frontend-v1.2.0
The .github/workflows/coordinate-release.yml workflow automates this process.
- Go to the main repository: Invoice-Liquidity-Network
- Navigate to Actions β Coordinate Cross-Repo Release
- Click Run workflow
- Fill in the required inputs:
- Version: Semantic version (e.g.,
v1.2.0) - Dry run (optional): Check to test without making changes
- Discord webhook (optional): Paste webhook URL for notifications
- Version: Semantic version (e.g.,
version:
description: Release version in semantic format (e.g., v1.2.0)
required: true
example: v1.2.0
dry_run:
description: Skip actual tagging, just simulate the process
required: false
default: false
discord_webhook:
description: Discord webhook URL for release notification
required: false
example: https://discordapp.com/api/webhooks/...The automated workflow performs these steps in sequence:
- Validate version format β Ensures version follows semantic versioning
- Tag smart contract repo β Creates a git tag in ILN-Smart-Contract
- Wait for smart contract CI β Polls GitHub Actions until deployment completes
- Update SDK contract IDs β Fetches new contract IDs and updates SDK
- Run SDK tests β Verifies SDK still works with new contract IDs
- Tag SDK release β Creates a git tag in Invoice-Liquidity-Network
- Update frontend SDK version β Updates package.json in ILN-Frontend
- Wait for frontend CI β Polls GitHub Actions until frontend CI completes
- Tag frontend release β Creates a git tag in ILN-Frontend
- Send Discord notification β Posts release summary to Discord (optional)
If the automated workflow encounters issues, you can perform a manual release:
# In ILN-Smart-Contract repo
git tag v1.2.0
git push origin v1.2.0
# Wait for CI to complete and verify contract IDs
# Document new contract IDs from CI logs# In Invoice-Liquidity-Network repo
# Update contract IDs in sdk/src/config.ts or similar
# Update SDK version in sdk/package.json
npm ci
npm run test
npm run build
git add .
git commit -m "chore(sdk): update contract IDs for v1.2.0"
git tag sdk-v1.2.0
git push origin main sdk-v1.2.0
# Optionally publish to npm
npm publish --workspace=sdk# In ILN-Frontend repo
# Update SDK dependency
npm install @invoice-liquidity/sdk@latest
npm run test
npm run build
git add .
git commit -m "chore(frontend): update SDK to v1.2.0"
git tag frontend-v1.2.0
git push origin main frontend-v1.2.0Use dry-run mode to test the entire workflow without making actual changes:
- Run the workflow with:
- Version:
v1.2.0 - Dry run: β (checked)
- Version:
The workflow will log all steps it would perform but skip tagging and pushing changes.
To enable the automated workflow, ensure:
Set these secrets in the main repository settings:
GITHUB_TOKENβ Already available viasecrets.GITHUB_TOKEN- No additional secrets required for basic functionality
To receive release notifications:
- Create a Discord server/channel (if not exists)
- Set up a webhook in Discord channel settings
- Copy the webhook URL
- Paste it when running the workflow in the "Discord webhook URL" input
The workflow uses the GitHub token to access sibling repositories. Ensure:
- All three repositories are in the same organization
- The token has sufficient permissions (typically default for same-org workflows)
If a release fails or needs to be rolled back:
git tag -d v1.2.0
git push origin --delete v1.2.0# If you need to revert to previous SDK version in frontend
npm install @invoice-liquidity/sdk@<previous-version>
git add package.json package-lock.json
git commit -m "chore: revert SDK to previous version"
git push origin main- The workflow waits up to 10 minutes for dependent CI to complete
- If CI is slow, extend the polling interval in the workflow file
- Verify that contract IDs are correctly exported from smart contract CI
- Check that SDK files are updated in the correct locations (typically
sdk/src/config.tsor similar)
- Check that SDK package.json version is published to npm before frontend tries to install
- Manually run
npm installin frontend after SDK release tag is created
- Verify webhook URL is correct
- Check Discord channel permissions for the webhook
- If webhook is invalid, the workflow will continue but log a warning
All deploy and release workflows support manual triggering from the GitHub UI:
| Workflow | Has workflow_dispatch |
Inputs |
|---|---|---|
deploy.yml |
Yes | network (testnet/mainnet), dry_run |
docs-deploy.yml |
Yes | None |
coordinate-release.yml |
Yes | version, dry_run, discord_webhook |
release.yml |
Yes | None (triggers changeset flow) |
sdk-release.yml |
Yes | None (requires v* tag ref) |
scripts-release.yml |
Yes | None (requires @iln/scripts@* tag ref) |
- Re-deploy docs after a failed automatic deployment: run
docs-deploy.ymlβ "Run workflow". - Re-cut a release after a failed publish: run
release.ymlβ "Run workflow" onmain, or push a new tag forsdk-release.yml/scripts-release.yml. - Dry-run a cross-repo release: run
coordinate-release.ymlwithdry_run: true.
Potential enhancements to the release process:
- Automated changelog generation based on commits since last release
- Automatic npm publish after SDK tag creation
- Slack notification alternative to Discord
- Release notes template population
- Mainnet vs testnet release coordination
- Automated frontend deploy to staging/production
The project publishes npm packages under two scopes:
| Scope | Owner | 2FA Required |
|---|---|---|
@iln |
Invoice Liquidity Network maintainers | Yes |
@invoice-liquidity |
Invoice Liquidity Network maintainers | Yes |
Both scopes must be registered under the project's control. Maintainers must verify scope ownership and 2FA on the publishing account before any publish workflow runs. Unclaimed or poorly-controlled scopes create a dependency-confusion/typosquatting risk.
The following internal packages are referenced in the monorepo but are not yet published to npm. They MUST NOT be installed from npm by external consumers; they resolve from the workspace instead.
| Local Name | Published Name | Status |
|---|---|---|
packages/cli |
@iln/cli |
Unpublished |
packages/test-utils |
@iln/test-utils |
Unpublished |
packages/scripts |
@iln/scripts |
Unpublished |
packages/sdk |
@iln/sdk-next |
Unpublished |
packages/mock-backend |
@iln/mock-backend |
Unpublished |
packages/indexer |
@iln/indexer |
Unpublished |
packages/invoice-sdk |
@iln/invoice-sdk |
Unpublished |
packages/eslint-config |
@iln/eslint-config |
Unpublished |
packages/upgrade-tests |
@iln/upgrade-tests |
Unpublished |
packages/shared |
@iln/shared |
Unpublished |
packages/react |
@iln/react |
Unpublished |
packages/opentelemetry |
@iln/opentelemetry |
Unpublished |
sdk/ |
@iln/sdk |
Published via sdk-release.yml |
cli/ |
@invoice-liquidity/cli |
Unpublished |
docs/ |
@invoice-liquidity/docs |
Unpublished |
indexer/ |
iln-indexer |
Unpublished |
notifications/ |
iln-notifications |
Unpublished |
Action required: Add a placeholders publish task to reserve these names if the project's standard practice is to prevent squatting. Coordinate with a maintainer who has npm registry access.
- Confirm
@ilnand@invoice-liquidityscopes are owned by the project org. - Confirm the npm automation token used in CI has
2FA-requiredpublish access. - Review the unpublished-but-referenced table above and reserve any new names before they appear in a public release.