Skip to content
Closed
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
1 change: 1 addition & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
- [ ] I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
- [ ] I have made corresponding changes to the documentation if needed
- [ ] If I added or changed GroveDB structure, I described it in the area's `structure.rs`, regenerated `grovedb-structure.json`, and checked the structure viewer link posted on this pull request
- [ ] If I added or changed a system contract's document schemas, I checked the contract viewer link posted on this pull request

**For repository code-owners and collaborators only**
- [ ] I have assigned this pull request to a milestone
134 changes: 134 additions & 0 deletions .github/workflows/system-contract-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
name: System Contract Preview (PR)

# When a pull request adds or changes a system contract's document schemas,
# post a link that opens each one in the contract viewer: a new contract on its
# own, a changed file or a new schema version compared with what it replaces.
# The viewer reads the files from GitHub itself; this only builds the links.

on:
pull_request:
types: [opened, synchronize, reopened]
paths:
- 'packages/*-contract/schema/**/*.json'
- '.github/workflows/system-contract-preview.yml'

permissions:
contents: read
pull-requests: write

concurrency:
group: system-contract-preview-${{ github.event.pull_request.number }}
cancel-in-progress: true

env:
VIEWER_URL: https://dashpay.github.io/contract-visualizer/

jobs:
preview:
name: Link the contract viewer
runs-on: ubuntu-24.04
steps:
- name: Find the changed system contracts and post the links
uses: actions/github-script@v7
with:
script: |
const pr = context.payload.pull_request;
const { owner, repo } = context.repo;
const viewer = process.env.VIEWER_URL;

// Compare against where the branch left the base, as GitHub's
// "Files changed" tab does, so schemas merged into the base since
// then do not show up as changed
let base = pr.base.sha;
try {
const { data } = await github.rest.repos.compareCommitsWithBasehead({
owner, repo, basehead: `${pr.base.sha}...${pr.head.sha}`, per_page: 1,
});
base = data.merge_base_commit.sha;
} catch (error) {
core.warning(`Could not find the merge base, using the base tip: ${error.message}`);
}

// A system contract's schemas: packages/<name>-contract/schema/v<N>/<file>.json.
// File names come from the pull request, so only names of this shape
// are used, and they are printed as code.
const SCHEMA = /^packages\/([a-z0-9-]+-contract)\/schema\/v([0-9]{1,3})\/([A-Za-z0-9._-]+\.json)$/;
const files = (await github.paginate(github.rest.pulls.listFiles, {
owner, repo, pull_number: pr.number, per_page: 100,
}))
.map((file) => ({ ...file, match: SCHEMA.exec(file.filename) }))
.filter((file) => file.match);

const headRepo = pr.head.repo.full_name;
const blob = (fullName, sha, path) => `https://github.com/${fullName}/blob/${sha}/${path}`;
const open = (source) => `${viewer}?url=${encodeURIComponent(source)}`;
const compare = (before, after) => `${viewer}?base=${encodeURIComponent(before)}&head=${encodeURIComponent(after)}`;

async function existsAtBase(path) {
try {
await github.rest.repos.getContent({ owner, repo, path, ref: base });
return true;
} catch (error) {
if (error.status === 404) return false;
throw error;
}
}

const rows = [];
for (const file of files.slice(0, 30)) {
const [, contract, version, name] = file.match;
const path = file.filename;
const at = `\`${path}\``;
if (file.status === 'removed') {
rows.push(`- ${at}: removed ([last version](${open(blob(`${owner}/${repo}`, base, path))}))`);
continue;
}
const head = blob(headRepo, pr.head.sha, path);
if (file.status === 'added') {
// A new schema version is compared with the newest earlier
// version of the same file
let previous = null;
for (let older = Number(version) - 1; older >= 1 && !previous; older -= 1) {
const candidate = `packages/${contract}/schema/v${older}/${name}`;
if (await existsAtBase(candidate)) previous = { path: candidate, version: older };
}
rows.push(previous
? `- ${at}: new version. **[Compare with \`v${previous.version}\`](${compare(blob(`${owner}/${repo}`, base, previous.path), head)})** · [open on its own](${open(head)})`
: `- ${at}: new contract. **[Open it in the contract viewer](${open(head)})**`);
continue;
}
// Modified or renamed: the file as the base had it, and as the pull request leaves it
const before = blob(`${owner}/${repo}`, base, file.status === 'renamed' && file.previous_filename ? file.previous_filename : path);
rows.push(`- ${at}: changed. **[Compare in the contract viewer](${compare(before, head)})** · [open on its own](${open(head)})`);
}
if (files.length > 30) rows.push(`- and ${files.length - 30} more`);

const marker = '<!-- system-contract-preview -->';
const body = [
marker,
'📜 **System contracts**',
'',
rows.length === 0
? 'This pull request no longer adds or changes a system contract\'s document schemas.'
: 'This pull request adds or changes system contract document schemas. The contract viewer diagrams each one, and a comparison marks what is added, changed and removed, with the update rule each change meets.',
'',
...rows,
'',
`_Compared \`${base.slice(0, 10)}\` with \`${pr.head.sha.slice(0, 10)}\`. Updated at ${new Date().toISOString()}_`,
].join('\n');

await core.summary.addRaw(body.replace(marker, '')).write();

// Fork pull requests run with a read-only token that cannot post comments
if (pr.head.repo.full_name !== `${owner}/${repo}`) {
core.notice(body.replace(marker, ''));
return;
}

const comments = await github.paginate(github.rest.issues.listComments, { owner, repo, issue_number: pr.number });
const existing = comments.find((comment) => comment.body.includes(marker));
if (existing) {
await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body });
} else if (rows.length > 0) {
await github.rest.issues.createComment({ owner, repo, issue_number: pr.number, body });
}
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
## [5.0.0-rc.8](https://github.com/dashpay/platform/compare/v5.0.0-rc.7...v5.0.0-rc.8) (2026-10-23)


### ⚠ BREAKING CHANGES

* **sdk:** version the non-unique identity lookup so 4.1 clients keep working (#5515)

### Bug Fixes

* **sdk:** verify operation proofs signed by older and newer protocol versions ([#5541](https://github.com/dashpay/platform/issues/5541))
* **sdk:** version the non-unique identity lookup so 4.1 clients keep working ([#5515](https://github.com/dashpay/platform/issues/5515))

## [5.0.0-rc.7](https://github.com/dashpay/platform/compare/v5.0.0-rc.6...v5.0.0-rc.7) (2026-10-21)


Expand Down
Loading
Loading