Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
95b82cc
ci: add build & test workflow and CI/CD documentation
aklenik Apr 10, 2026
1a5cd67
refactor: reorganize RegistryTest by method-based grouping
Nesar976 Apr 10, 2026
51fd897
docs(site): scaffold and migrate markdown content
AnvayKharb Apr 10, 2026
a2a07db
ci(docs): add mkdocs config and pages deployment workflow
AnvayKharb Apr 10, 2026
bea5d17
ci(docs): fix tag deployment conflict in mike workflow
AnvayKharb Apr 10, 2026
bcf4b51
docs: enforce strict mkdocs and clean migrated CI/CD page
AnvayKharb Apr 15, 2026
88668ae
ci(docs): remove redundant mkdocs build steps
AnvayKharb Apr 15, 2026
816adc4
feat: Context and cross-chaincode exception handling
Sreejesh06 May 2, 2026
caf354b
feat: Add and update stub middleware logic
Sreejesh06 May 3, 2026
c2364c6
feat: Core registry operations and collectors
Sreejesh06 May 4, 2026
21cd9c3
feat: Implement rich query builder patterns
Sreejesh06 May 5, 2026
9a2a995
docs: fix typos in README.md
Maanvi212006 Apr 21, 2026
d31f06d
feat: Add endorsement policy handling
Sreejesh06 May 6, 2026
e9dcdbd
test: Add prototype tests and sample chaincode
Sreejesh06 May 7, 2026
29c719c
chore: Update settings
Sreejesh06 May 8, 2026
8b20383
chore: Apply spotless formatting and fix Registry endorsement validation
Sreejesh06 May 9, 2026
955f6bc
ci: add automatic labelling of new issues with needs-triage
bzp99 Jun 10, 2026
dfbcb4b
ci: add automatic flagging of non-design-approved PRs
bzp99 Jun 10, 2026
caaf2a7
ci: mark old non-approved PRs stale
bzp99 Jun 10, 2026
998e523
docs(ci): document new CI workflows
bzp99 Jun 10, 2026
0a2d1f4
feat: add EntityType annotation
Sreejesh06 Apr 11, 2026
c6222cf
feat: validate EntityType annotation parameters
Sreejesh06 Jul 20, 2026
229a573
Merge branch 'main' into query-builder-prototype
Sreejesh06 Aug 15, 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
177 changes: 177 additions & 0 deletions .github/scripts/check_design_approval.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/*
* Checks that a PR has at least one linked issue carrying the `design/approved` label.
* If not, it applies a `needs-approved-issue` label and posts an explanatory comment.
*
* Usage (called by the workflow via actions/github-script):
* const script = require('./.github/scripts/check_design_approval.js')
* await script({ github, context, core })
*/

const REQUIRED_LABEL = 'design/approved'
const FLAG_LABEL = 'needs-approved-issue'

// Fetch everything we need in a single GraphQL query:
// - Linked issues + their labels
// - Current labels on the PR
// - Existing bot comments on the PR (to avoid duplicate comments)
const QUERY = `
query CheckDesignApproval($owner: String!, $repo: String!, $prNumber: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $prNumber) {
author { login }
labels(first: 10) {
nodes { name }
}
comments(last: 50) {
nodes {
body
author {
login
__typename
}
}
}
closingIssuesReferences(first: 10) {
nodes {
number
labels(first: 10) {
nodes { name }
}
}
}
}
}
}
`

/**
* Ensure a label exists in the repo, creating it if necessary.
* @param {object} github - Octokit instance from github-script
* @param {object} repo - { owner, repo }
* @param {string} label
*/
async function ensureLabelExists (github, repo, label) {
try {
await github.rest.issues.getLabel({ ...repo, name: label })
} catch (err) {
if (err.status === 404) {
await github.rest.issues.createLabel({
...repo,
name: label,
color: 'fbca04',
description: 'PR is not linked to a design/approved issue'
})
} else {
throw err
}
}
}

/**
* Entry point called by the actions/github-script workflow step.
*/
module.exports = async ({ github, context, core }) => {
const { owner, repo } = context.repo
const prNumber = context.payload.pull_request.number

core.info(`Checking PR #${prNumber}`)

// ── 1. Single GraphQL query that reads all data ─────────────────────
const { repository } = await github.graphql(QUERY, {
owner,
repo,
prNumber
})

const pr = repository.pullRequest
const prAuthor = pr.author.login
const currentLabelNames = pr.labels.nodes.map((l) => l.name)
const linkedIssues = pr.closingIssuesReferences.nodes

core.info(
linkedIssues.length
? `Found ${linkedIssues.length} linked issue(s): ${linkedIssues.map((i) => `#${i.number}`).join(', ')}`
: 'No linked issues found.'
)

// ── 2. Check linked issues for the required label ───────────────────
let approvedIssue = null
for (const issue of linkedIssues) {
const issueLabels = issue.labels.nodes.map((l) => l.name)
core.info(`Issue #${issue.number} labels: [${issueLabels.join(', ')}]`)
if (issueLabels.includes(REQUIRED_LABEL)) {
core.info(`✅ Issue #${issue.number} has '${REQUIRED_LABEL}' – PR passes.`)
approvedIssue = issue
break
}
}

const alreadyFlagged = currentLabelNames.includes(FLAG_LABEL)

// ── 3a. PR passes; clean up flag label if previously applied ────────
if (approvedIssue) {
if (alreadyFlagged) {
core.info(`Removing '${FLAG_LABEL}' label as the PR now passes.`)
await github.rest.issues.removeLabel({
owner,
repo,
issue_number: prNumber,
name: FLAG_LABEL
})
}
return
}

// ── 3b. PR fails; apply label + comment ─────────────────────────────
core.info(`PR #${prNumber} does not meet requirements.`)

await ensureLabelExists(github, { owner, repo }, FLAG_LABEL)

if (!alreadyFlagged) {
await github.rest.issues.addLabels({
owner,
repo,
issue_number: prNumber,
labels: [FLAG_LABEL]
})
core.info(`Applied '${FLAG_LABEL}' label.`)
}

// Bot comments have __typename "Bot" on the author node in GraphQL.
const alreadyCommented = pr.comments.nodes.some(
(c) => c.author.__typename === 'Bot' && c.body.includes(REQUIRED_LABEL)
)
if (!alreadyCommented) {
const message =
linkedIssues.length === 0
? `Hey @${prAuthor}, thanks for the contribution! 👋

This PR was flagged because it has no linked issues. Please link one using a closing keyword in the PR description; for example:

\`\`\`
Closes #<issue-number>
\`\`\`

The linked issue must also carry the \`${REQUIRED_LABEL}\` label. If no issue exists yet, please open one and get design approval from the maintainers first.`
: `Hey @${prAuthor}, thanks for the contribution! 👋

This PR was flagged because the linked issue(s) (${linkedIssues.map((i) => `#${i.number}`).join(', ')}) do not have the \`${REQUIRED_LABEL}\` label.

Please ensure the linked issue has been through the design approval process and carries the \`${REQUIRED_LABEL}\` label before this PR can be merged.`

await github.rest.issues.createComment({
owner,
repo,
issue_number: prNumber,
body: message
})
core.info('Posted explanatory comment.')
} else {
core.info('Comment already exists; skipping to avoid spam.')
}

// Signal failure so the check shows as ❌ in the PR's status checks.
core.setFailed(
`PR #${prNumber} is not linked to an issue with the '${REQUIRED_LABEL}' label.`
)
}
62 changes: 62 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Build & Test

on:
push:
branches: ['**']
paths:
- 'lib/**'
- '*.gradle.kts'
- 'gradle/**'
- 'gradlew*'
- '.github/workflows/build.yml'
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
paths:
- 'lib/**'
- '*.gradle.kts'
- 'gradle/**'
- 'gradlew*'
- '.github/workflows/build.yml'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
build-and-test:
name: Build & Test
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Java 17
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4

- name: Check formatting
run: ./gradlew spotlessCheck

- name: Assemble
run: ./gradlew assemble

- name: Run tests
run: ./gradlew test

- name: Upload test report
if: always()
uses: actions/upload-artifact@v4
with:
name: test-report
path: lib/build/reports/tests/test/
retention-days: 14
27 changes: 27 additions & 0 deletions .github/workflows/check_design_approval.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
name: Flag PRs that do not have associated design/approved issues


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


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


jobs:
check:
name: Linked issue has design/approved
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Run design-approval check
uses: actions/github-script@v9
with:
script: |-
const script = require('./.github/scripts/check_design_approval.js')
await script({ github, context, core })
56 changes: 56 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Deploy Documentation

on:
push:
branches:
- main
tags:
- "v*.*.*"

permissions:
contents: write

jobs:
deploy-latest:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: pip install -r docs/requirements.txt
- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Deploy latest
run: |
mike deploy --push --allow-empty --update-aliases latest
mike set-default --push latest

deploy-version:
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: pip install -r docs/requirements.txt
- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Extract version
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Deploy version
run: |
mike deploy --push --allow-empty ${{ steps.version.outputs.VERSION }}
31 changes: 31 additions & 0 deletions .github/workflows/stale_not_approved.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: >-
Mark PRs without design/approved linked issues as stale
and eventually close them


on:
schedule:
- cron: 30 1 * * *


permissions:
pull-requests: write


jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v10
with:
stale-pr-message: |-
This PR has been automatically marked as stale due to inactivity.
It will be closed in 60 days if no further activity occurs.
days-before-stale: 14
days-before-close: 60
days-before-issue-stale: -1
days-before-issue-close: -1
stale-pr-label: stale
exempt-pr-labels: pinned,security
any-of-labels: needs-approved-issue
24 changes: 24 additions & 0 deletions .github/workflows/triage_label.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
name: Auto-add needs-triage labels to new issues


on:
issues:
types: [opened]


permissions:
issues: write


jobs:
label:
runs-on: ubuntu-latest
steps:
- run: >-
gh issue
edit ${{ github.event.issue.number }}
--add-label needs-triage
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,4 @@ gradle-app.setting
### Custom ###
.idea/
lib/bin/
site/
Loading
Loading