Skip to content

Commit 7c8e746

Browse files
authored
Merge branch 'main' into test-names
Signed-off-by: exploreriii <133720349+exploreriii@users.noreply.github.com>
2 parents 2cafb62 + bb49a03 commit 7c8e746

16 files changed

Lines changed: 1458 additions & 146 deletions
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
## 🕵️ Release-Gate Audit: Breaking Changes & Architecture
2+
3+
You are performing a **Senior Release Engineer** audit on this diff. Your goal is to identify risks that could impact downstream users or system stability.
4+
5+
### 🚨 Critical Instructions
6+
- **Ignore** linting, variable naming, or stylistic preferences.
7+
- **Focus** on public API surface, data schemas, and logic flow.
8+
- **Be Concise**: Use bullet points. If no risks are found, state "No breaking changes identified."
9+
10+
---
11+
12+
### 1. 🛠️ Public API & Contract Changes
13+
Identify any modifications to the public-facing interface.
14+
- **Removals/Renames**: Are any classes, methods, or variables renamed or removed?
15+
- **Signature Changes**: Have parameter types or return types changed in a way that breaks existing calls?
16+
- **Defaults**: Have default values for arguments changed?
17+
18+
### 2. 🏗️ Architectural Integrity
19+
- **Dependency Changes**: Highlight any new external libraries or significant version bumps.
20+
- **Side Effects**: Are there new global states, singletons, or changes to how the application initializes?
21+
- **Resource Usage**: Does this diff introduce patterns that might impact memory or CPU (e.g., new loops, heavy recursive calls)?
22+
23+
### 3. 📉 Backward Compatibility & Data
24+
- **Persistence**: If applicable, do database schema changes or file format changes require a migration?
25+
- **Protocol**: If this communicates via API/WebSockets, is the payload structure still compatible with the previous version?
26+
27+
### 4. 🧪 Testing & Validation
28+
- **Coverage Gap**: Are there major logic additions that lack corresponding test files in the diff?
29+
- **Edge Cases**: Identify at least one "what-if" scenario that might cause a failure (e.g., "What if the network is down during this new initialization step?").
30+
31+
---
32+
33+
### 🏁 Summary Verdict
34+
Provide a 1-sentence summary of the "Safety" of this release candidate.
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/**
2+
* Posts a single "@coderabbit review" comment on release PRs, embedding the
3+
* release review prompt. Designed to run with:
4+
* - permissions: contents: read, pull-requests: write
5+
*
6+
* Safety:
7+
* - Only runs for maintainer-authored PRs (MEMBER/OWNER)
8+
* - Dedupe via hidden marker comment
9+
*/
10+
11+
const fs = require("fs");
12+
const path = require("path");
13+
14+
const MARKER = "<!-- coderabbit-release-gate: v1 -->";
15+
16+
17+
function loadPrompt() {
18+
const promptPath = path.join(
19+
process.env.GITHUB_WORKSPACE || ".",
20+
".github/coderabbit/release-pr-prompt.md"
21+
);
22+
try {
23+
const content = fs.readFileSync(promptPath, "utf8").trim();
24+
if (!content) {
25+
throw new Error("Release prompt file is empty");
26+
}
27+
return content;
28+
} catch (error) {
29+
throw new Error(`Failed to load release prompt from ${promptPath}: ${error.message}`);
30+
}
31+
}
32+
33+
34+
async function commentAlreadyExists({ github, owner, repo, issue_number }) {
35+
try {
36+
const data = await github.paginate(github.rest.issues.listComments, {
37+
owner,
38+
repo,
39+
issue_number,
40+
per_page: 100,
41+
});
42+
data.forEach(c => {
43+
if (c.body && c.body.includes(MARKER)) {
44+
console.log(`FOUND MATCH in comment by ${c.user.login}: ${c.html_url}`);
45+
}
46+
});
47+
return data.some((c) => typeof c.body === "string" && c.body.includes(MARKER));
48+
}
49+
catch (error) {
50+
console.error(`Error checking for existing comments: ${error.message}`);
51+
return true; // Fail closed to avoid duplicates if we can't verify
52+
}
53+
}
54+
55+
56+
function buildBody({ prompt, headRef }) {
57+
return [
58+
"@coderabbit review",
59+
"",
60+
MARKER,
61+
"",
62+
"## 🚀 Release Gate: Cumulative Audit",
63+
"> **Notice to Reviewer**: This is a checkpoint PR for a new release. While the diff here primarily updates versioning and the Changelog, your audit must cover the **entire cumulative scope** of changes since the last version tag.",
64+
"",
65+
"### 🎯 Audit Objectives",
66+
"- Analyze all features merged into `main` since the previous release.",
67+
"- Identify breaking changes in the public API or protocol.",
68+
"- Verify architectural integrity across the Hiero SDK Python modules.",
69+
"",
70+
"<details>",
71+
"<summary><b>View Senior Audit Constraints</b></summary>",
72+
"",
73+
prompt,
74+
"",
75+
"</details>",
76+
"",
77+
"---",
78+
`*Auditing Branch: \`${headRef}\` against the project history.*`,
79+
].join("\n");
80+
}
81+
82+
function getSkipReason(pr) {
83+
if (!pr) {
84+
return "No pull_request payload; exiting.";
85+
}
86+
87+
if (!["MEMBER", "OWNER"].includes(pr.author_association)) {
88+
return `author_association=${pr.author_association}; skipping.`;
89+
}
90+
91+
const title = (pr.title || "").toLowerCase();
92+
const isReleaseTitle =
93+
title.startsWith("chore: release v") || title.startsWith("release v");
94+
95+
if (!isReleaseTitle) {
96+
return "Not a release PR title; skipping.";
97+
}
98+
99+
return null;
100+
}
101+
102+
module.exports = async ({ github, context }) => {
103+
let issue_number = "unknown";
104+
let headRef = "?";
105+
let baseRef = "?";
106+
107+
try {
108+
const owner = context.repo.owner;
109+
const repo = context.repo.repo;
110+
const pr = context.payload.pull_request;
111+
112+
const skipReason = getSkipReason(pr);
113+
if (skipReason) {
114+
console.log(skipReason);
115+
return;
116+
}
117+
118+
issue_number = pr.number;
119+
if (await commentAlreadyExists({ github, owner, repo, issue_number })) {
120+
console.log("Release gate comment already exists. Skipping.");
121+
return;
122+
}
123+
124+
headRef = pr.head?.ref || "unknown";
125+
baseRef = pr.base?.ref || "unknown";
126+
127+
const prompt = loadPrompt();
128+
const body = buildBody({ prompt, headRef });
129+
130+
await github.rest.issues.createComment({
131+
owner,
132+
repo,
133+
issue_number,
134+
body,
135+
});
136+
137+
console.log("Posted CodeRabbit release-gate comment.");
138+
console.log(`PR #${issue_number} (${headRef}${baseRef})`);
139+
} catch (error) {
140+
console.error(`Error in release PR coderabbit gate: ${error.message}`);
141+
console.log(`PR #${issue_number || 'unknown'} (${headRef || '?'}${baseRef || '?'})`);
142+
}
143+
};

.github/spam-list.txt

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
KubanjaElijahEldred
2-
by22Jy
3-
CODEAbhinav-art
4-
zhanglinqian
5-
Halbot100
6-
roberthallers
7-
SergioChan
8-
ndpvt-web
9-
OnlyTerp
10-
shixian-HFUT
11-
Yuki9814
1+
KubanjaElijahEldred
2+
by22Jy
3+
CODEAbhinav-art
4+
zhanglinqian
5+
Halbot100
6+
roberthallers
7+
SergioChan
8+
ndpvt-web
9+
OnlyTerp
10+
shixian-HFUT
11+
Yuki9814
12+
ashrafzunaira18

.github/workflows/pr-check-test.yml renamed to .github/workflows/pr-check-secondary-unit-integration-test.yml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
name: Hiero Solo Integration & Unit Tests
2-
1+
name: Secondary PR Check - Hiero Solo Integration & Unit Tests
32
on:
43
push:
54
branches:
@@ -9,21 +8,27 @@ on:
98
- "docs/**"
109
- "examples/**"
1110
- "tck/**"
11+
- "tests/fuzz/**"
1212
- ".github/**"
13-
- "!.github/workflows/pr-check-test.yml"
13+
- "!.github/workflows/pr-check-secondary-unit-integration-test.yml"
1414
pull_request:
1515
paths-ignore:
1616
- "**/*.md"
1717
- "docs/**"
1818
- "examples/**"
1919
- "tck/**"
20+
- "tests/fuzz/**"
2021
- ".github/**"
21-
- "!.github/workflows/pr-check-test.yml"
22+
- "!.github/workflows/pr-check-secondary-unit-integration-test.yml"
2223
workflow_dispatch: {}
2324

2425
permissions:
2526
contents: read
2627

28+
concurrency:
29+
group: pr-check-${{ github.event.pull_request.number || github.ref }}
30+
cancel-in-progress: true
31+
2732
jobs:
2833
unit-tests:
2934
name: Unit Tests (Python ${{ matrix.python-version }})

.github/workflows/publish.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ jobs:
3131
python-version: '3.14'
3232

3333
- name: Upgrade pip
34-
run: pip install --upgrade pip
34+
run: pip install "pip==26.0.1"
3535

3636
- name: Install build, pdm-backend, and grpcio-tools
37-
run: pip install build pdm-backend "grpcio-tools>=1.76.0"
37+
run: pip install build pdm-backend "grpcio-tools==1.76.0"
3838

3939
- name: Generate Protobuf
4040
run: python generate_proto.py
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: CodeRabbit Release Gate Comment
2+
3+
on:
4+
pull_request:
5+
types: [opened, reopened, synchronize, edited]
6+
7+
permissions:
8+
contents: read
9+
pull-requests: write
10+
11+
concurrency:
12+
group: coderabbit-release-gate-${{ github.event.pull_request.number }}
13+
cancel-in-progress: true
14+
15+
jobs:
16+
coderabbit-release-gate:
17+
runs-on: ubuntu-latest
18+
# Only run for release PRs /title check as initial filter
19+
if: |
20+
github.event.pull_request &&
21+
(github.event.pull_request.author_association == 'MEMBER' ||
22+
github.event.pull_request.author_association == 'OWNER') &&
23+
(startsWith(github.event.pull_request.title, 'chore: release v') ||
24+
startsWith(github.event.pull_request.title, 'release v'))
25+
26+
steps:
27+
- name: Harden the runner
28+
uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1
29+
with:
30+
egress-policy: audit
31+
32+
- name: Checkout repository
33+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
34+
35+
- name: Post CodeRabbit release-gate prompt comment
36+
env:
37+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd #v8.0.0
39+
with:
40+
script: |
41+
const script = require('./.github/scripts/release-pr-coderabbit-gate.js');
42+
await script({ github, context});

CHANGELOG.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Changelog
1+
# Changelog
22

33
All notable changes to this project will be documented in this file.
44
This project adheres to [Semantic Versioning](https://semver.org).
@@ -7,24 +7,29 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
77
## [Unreleased]
88

99
### Src
10-
-
10+
- Exposed all missing `TransactionRecord` protobuf fields `consensusTimestamp`, `scheduleRef`, `assessed_custom_fees`, `automatic_token_associations`, `parent_consensus_timestamp`, `alias`, `ethereum_hash`, `paid_staking_rewards`, `evm_address`, `contractCreateResult` with proper `None` handling, PRNG oneof handling with unset values return `None` instead of default values 0 / b"" (#1636)
1111

1212
### Tests
1313
- Refactor `mock_server` setup for network level TLS handling and added thread safety
1414
- Ensured /fuzz and /unit tests end in `_test.py` (#2063)
1515

1616
### Examples
1717

18+
- Add the missing `setup_client()` docstring in `examples/tokens/token_dissociate_transaction.py` for consistency with the other example functions. (#2058)
1819

1920
### Docs
2021

2122

2223
### .github
24+
- chore: pin pip packages to exact versions in publish.yml to improve supply chain security and reproducibility (#2056)
2325
- chore: update GitHub Actions runners from ubuntu-latest to hl-sdk-py-lin-md (#2021)
2426
- Refactored the Advanced Issue Template to V2 with stricter prerequisites and a focus on architectural design (#2016).
2527
- Refactored the Advanced Issue Template to ensure PR-level quality checklists do not block maintainers during issue creation (#2036)
28+
- chore: add concurrency to unit and integration tests (#2071)
2629
- Add automated label sync workflow to propagate labels from linked issues to pull requests (#1716)
2730
- Added support for fuzz and TCK test naming check, converted to JS from shell and ensure it checks all tests (#2064)
31+
- chore: update spam list (#2035)
32+
- Add CodeRabbit release gate workflow and prompt for PR audits `release-pr-prompt.md`, `release-pr-coderabbit-gate.yml` and `release-pr-coderabbit-gate.js`
2833

2934
## [0.2.3] - 2026-03-26
3035

@@ -36,6 +41,8 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
3641
- Fix the TransactionGetReceiptQuery to raise ReceiptStatusError for the non-retryable and non success receipt status
3742
- Refactor `AccountInfo` to use the existing `StakingInfo` wrapper class instead of flattened staking fields. Access is now via `info.staking_info.staked_account_id`, `info.staking_info.staked_node_id`, and `info.staking_info.decline_reward`. The old flat accessors (`info.staked_account_id`, `info.staked_node_id`, `info.decline_staking_reward`) are still available as deprecated properties and will emit a `DeprecationWarning`. (#1366)
3843
- Added abstract `Key` supper class to handle various proto Keys.
44+
45+
3946
### Examples
4047

4148
### Tests

examples/tokens/token_dissociate_transaction.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020

2121
def setup_client():
22+
"""Initialize the Hiero client from environment variables and print connection info."""
2223
client = Client.from_env()
2324
print(f"Network: {client.network.network}")
2425
print(f"Client set up with operator id {client.operator_account_id}")

0 commit comments

Comments
 (0)