Sitelet https://github.com/Dargon789/account/commit/c2a5806bab1e7028de0fb72c4243fa310d5ac374
Skip to content

Commit c2a5806

Browse files
legion2002claude
andauthored
fix: update version bump CI to match new requirements (ithacaxyz#233)
* fix: update version bump CI to match new requirements - Remove package.json version bumping - Implement contract-specific version bump logic: - IthacaAccount changes only bump IthacaAccount version - Orchestrator changes bump both Orchestrator and IthacaAccount versions - SimpleFunder changes only bump SimpleFunder version - Update CI workflow to only commit Solidity file changes - Update scripts to handle contract-specific version bumping Fixes ithacaxyz#230 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: correct GitHub Actions references for PR context - Use proper PR references in checkout and push steps - Fix environment variable handling in check-bytecode-changes.js - Use github.event.pull_request.head.ref/sha for PR context * fix: resolve YAML syntax error in commit message - Changed multi-line commit message to single line to avoid YAML parsing issues * fix: improve version bump detection to check specific contracts Previously, the script only checked if ANY Solidity files were modified, which could incorrectly skip automatic bumps when some contracts were manually bumped but others still needed bumping. Now checks each specific contract to see if its version was already manually bumped, and only auto-bumps the remaining contracts. This prevents: - Skipping auto-bumps when only some contracts were manually updated - Double-bumping contracts that were already manually bumped 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent ae0b0ef commit c2a5806

3 files changed

Lines changed: 145 additions & 49 deletions

File tree

‎.github/workflows/version-check.yaml‎

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ jobs:
1717
uses: actions/checkout@v4
1818
with:
1919
fetch-depth: 0
20+
ref: ${{ github.event.pull_request.head.ref }}
2021
token: ${{ secrets.GITHUB_TOKEN }}
2122

2223
- name: Setup Node.js
@@ -43,7 +44,7 @@ jobs:
4344
4445
- name: Build contracts on PR branch
4546
run: |
46-
git checkout ${{ github.head_ref }}
47+
git checkout ${{ github.event.pull_request.head.sha }}
4748
forge clean
4849
forge install
4950
forge build --force
@@ -60,37 +61,30 @@ jobs:
6061
git config --local user.email "action@github.com"
6162
git config --local user.name "GitHub Action"
6263
63-
# Get current version
64-
CURRENT_VERSION=$(node -p "require('./package.json').version")
64+
# Get the contracts that need bumping
65+
CONTRACTS_TO_BUMP="${{ steps.check.outputs.contracts_to_bump }}"
6566
66-
# Bump patch version
67-
IFS='.' read -r -a version_parts <<< "$CURRENT_VERSION"
68-
PATCH=$((version_parts[2] + 1))
69-
NEW_VERSION="${version_parts[0]}.${version_parts[1]}.$PATCH"
67+
echo "Bumping versions for contracts: $CONTRACTS_TO_BUMP"
7068
71-
echo "Bumping version from $CURRENT_VERSION to $NEW_VERSION"
69+
# Update Solidity files using the upgrade script with specific contracts
70+
CONTRACTS_TO_BUMP="$CONTRACTS_TO_BUMP" node prep/update-version.js
7271
73-
# Update package.json
74-
npm version $NEW_VERSION --no-git-tag-version
75-
76-
# Update Solidity files using the upgrade script
77-
node prep/update-version.js
78-
79-
# Commit changes
80-
git add .
81-
git commit -m "chore: bump version to $NEW_VERSION due to bytecode changes"
72+
# Commit changes (only Solidity files, not package.json)
73+
git add src/*.sol
74+
git commit -m "chore: bump contract versions due to bytecode changes - Contracts updated: $CONTRACTS_TO_BUMP"
8275
8376
# Push to the PR branch
84-
git push origin HEAD:${{ github.head_ref }}
77+
git push origin HEAD:${{ github.event.pull_request.head.ref }}
8578
8679
- name: Create PR comment
8780
if: steps.check.outputs.needs_version_bump == 'true'
8881
uses: actions/github-script@v7
8982
with:
9083
script: |
84+
const contractsToBump = '${{ steps.check.outputs.contracts_to_bump }}';
9185
github.rest.issues.createComment({
9286
issue_number: context.issue.number,
9387
owner: context.repo.owner,
9488
repo: context.repo.repo,
95-
body: '🤖 Bytecode changes detected! Version has been automatically bumped and EIP-712 domain versions have been updated.'
89+
body: `🤖 Bytecode changes detected! EIP-712 domain versions have been automatically updated for: ${contractsToBump}`
9690
})

‎prep/check-bytecode-changes.js‎

Lines changed: 102 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,25 @@ const fs = require("fs");
44
const path = require("path");
55
const crypto = require("crypto");
66

7-
// Main contracts to check for bytecode changes
8-
// When any dependency (parent contracts, libraries, interfaces) changes,
9-
// it will be reflected in the bytecode of these contracts
10-
const CONTRACTS_TO_CHECK = [
11-
"IthacaAccount.sol/IthacaAccount.json",
12-
"Orchestrator.sol/Orchestrator.json",
13-
];
7+
// Contract configuration
8+
// Each contract specifies which other contracts should be bumped when it changes
9+
const CONTRACT_CONFIG = {
10+
"IthacaAccount.sol/IthacaAccount.json": {
11+
name: "IthacaAccount",
12+
bumpsWhenChanged: [], // Account changes don't bump other contracts
13+
},
14+
"Orchestrator.sol/Orchestrator.json": {
15+
name: "Orchestrator",
16+
bumpsWhenChanged: ["IthacaAccount"], // Orchestrator changes bump Account
17+
},
18+
"SimpleFunder.sol/SimpleFunder.json": {
19+
name: "SimpleFunder",
20+
bumpsWhenChanged: [], // SimpleFunder changes only bump itself
21+
},
22+
};
23+
24+
// All contracts to check for bytecode changes
25+
const CONTRACTS_TO_CHECK = Object.keys(CONTRACT_CONFIG);
1426

1527
function getBytecodeHash(artifactPath) {
1628
try {
@@ -34,7 +46,7 @@ function getBytecodeHash(artifactPath) {
3446
}
3547

3648
function compareArtifacts(baseDir, prDir) {
37-
const changes = [];
49+
const changes = {};
3850

3951
for (const contract of CONTRACTS_TO_CHECK) {
4052
const basePath = path.join(baseDir, contract);
@@ -44,28 +56,82 @@ function compareArtifacts(baseDir, prDir) {
4456
const prHash = getBytecodeHash(prPath);
4557

4658
if (baseHash && prHash && baseHash !== prHash) {
47-
changes.push(contract);
59+
changes[contract] = true;
4860
console.log(`Bytecode changed: ${contract}`);
4961
}
5062
}
5163

5264
return changes;
5365
}
5466

55-
function checkVersionBump() {
67+
function determineContractsToBump(bytecodeChanges) {
68+
const contractsToBump = new Set();
69+
70+
for (const [contractPath, changed] of Object.entries(bytecodeChanges)) {
71+
if (changed) {
72+
const config = CONTRACT_CONFIG[contractPath];
73+
74+
// The contract itself needs to be bumped
75+
contractsToBump.add(config.name);
76+
77+
// Also bump any contracts specified in bumpsWhenChanged
78+
for (const otherContract of config.bumpsWhenChanged) {
79+
contractsToBump.add(otherContract);
80+
}
81+
}
82+
}
83+
84+
return Array.from(contractsToBump);
85+
}
86+
87+
function checkManualVersionBumps(contractsToBump) {
5688
try {
57-
// Check if package.json has been modified in this PR
58-
const gitStatus = require("child_process")
59-
.execSync("git diff --name-only origin/$GITHUB_BASE_REF...HEAD", {
89+
// Check which specific contracts have already had their versions manually bumped
90+
const baseRef = process.env.GITHUB_BASE_REF || 'main';
91+
const versionRegex = /version = "(\d+\.\d+\.\d+)";/;
92+
const alreadyBumpedContracts = [];
93+
94+
// Get the diff for Solidity files
95+
const gitDiff = require("child_process")
96+
.execSync(`git diff origin/${baseRef}...HEAD -- src/*.sol`, {
6097
encoding: "utf8",
61-
})
62-
.trim()
63-
.split("\n");
64-
65-
return gitStatus.includes("package.json");
98+
});
99+
100+
// Check each contract that needs bumping
101+
for (const contractName of contractsToBump) {
102+
// Look for version changes for this specific contract in the diff
103+
const contractPattern = new RegExp(`contract\\s+${contractName}[\\s\\S]*?version = "\\d+\\.\\d+\\.\\d+";`, 'g');
104+
const contractSection = gitDiff.match(contractPattern);
105+
106+
if (contractSection) {
107+
// Check if there's a version change in this contract's section
108+
const lines = gitDiff.split('\n');
109+
let inContract = false;
110+
let foundVersionChange = false;
111+
112+
for (const line of lines) {
113+
if (line.includes(`contract ${contractName}`)) {
114+
inContract = true;
115+
}
116+
if (inContract && line.startsWith('+') && versionRegex.test(line) && !line.startsWith('+++')) {
117+
foundVersionChange = true;
118+
alreadyBumpedContracts.push(contractName);
119+
break;
120+
}
121+
if (inContract && line.includes('contract ') && !line.includes(contractName)) {
122+
// We've moved to a different contract
123+
break;
124+
}
125+
}
126+
}
127+
}
128+
129+
// Return contracts that still need bumping (not manually bumped)
130+
return contractsToBump.filter(c => !alreadyBumpedContracts.includes(c));
66131
} catch (error) {
67-
console.error("Error checking git status:", error.message);
68-
return false;
132+
console.error("Error checking manual version bumps:", error.message);
133+
// If there's an error, assume all contracts need bumping
134+
return contractsToBump;
69135
}
70136
}
71137

@@ -81,23 +147,31 @@ function main() {
81147
const [baseDir, prDir] = args;
82148

83149
console.log("Checking bytecode changes...");
84-
const changes = compareArtifacts(baseDir, prDir);
150+
const bytecodeChanges = compareArtifacts(baseDir, prDir);
151+
const changedContracts = Object.values(bytecodeChanges).filter(Boolean).length;
152+
153+
if (changedContracts > 0) {
154+
console.log(`\nFound bytecode changes in ${changedContracts} contracts`);
85155

86-
if (changes.length > 0) {
87-
console.log(`\nFound bytecode changes in ${changes.length} contracts`);
156+
// Determine which contracts need version bumps
157+
const contractsToBump = determineContractsToBump(bytecodeChanges);
158+
console.log(`\nContracts that need version bumps: ${contractsToBump.join(", ")}`);
88159

89-
const versionBumped = checkVersionBump();
160+
// Check which contracts have already been manually bumped
161+
const contractsStillNeedingBump = checkManualVersionBumps(contractsToBump);
90162

91-
if (!versionBumped) {
92-
console.log("Version has not been bumped - automatic bump required");
163+
if (contractsStillNeedingBump.length > 0) {
164+
console.log(`Contracts still needing version bumps: ${contractsStillNeedingBump.join(", ")}`);
165+
console.log("Automatic bump required for remaining contracts");
93166
// Use modern GitHub Actions output syntax
94167
console.log(`::set-output name=needs_version_bump::true`);
168+
console.log(`::set-output name=contracts_to_bump::${contractsStillNeedingBump.join(",")}`);
95169
fs.appendFileSync(
96170
process.env.GITHUB_OUTPUT || "/dev/null",
97-
"needs_version_bump=true\n"
171+
`needs_version_bump=true\ncontracts_to_bump=${contractsStillNeedingBump.join(",")}\n`
98172
);
99173
} else {
100-
console.log("Version has already been bumped");
174+
console.log("All required contract versions have already been updated");
101175
console.log(`::set-output name=needs_version_bump::false`);
102176
fs.appendFileSync(
103177
process.env.GITHUB_OUTPUT || "/dev/null",

‎prep/update-version.js‎

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,19 @@
22
const { readSync, writeSync, forEachWalkSync } = require('./common.js');
33

44
async function main() {
5-
const newVersion = JSON.parse(readSync('package.json')).version;
5+
// Get contracts to bump from environment variable or command line
6+
const contractsToBump = process.env.CONTRACTS_TO_BUMP
7+
? process.env.CONTRACTS_TO_BUMP.split(',')
8+
: process.argv.slice(2);
9+
10+
if (contractsToBump.length === 0) {
11+
console.error('No contracts specified to bump. Usage: update-version.js [contract1] [contract2] ...');
12+
console.error('Or set CONTRACTS_TO_BUMP environment variable');
13+
process.exit(1);
14+
}
15+
16+
console.log(`Contracts to bump versions: ${contractsToBump.join(', ')}`);
17+
618
const versionRegex = /version = "(\d+\.\d+\.\d+)";/;
719

820
forEachWalkSync(['src'], srcPath => {
@@ -11,9 +23,25 @@ async function main() {
1123
const src = readSync(srcPath);
1224
if (src.indexOf('_domainNameAndVersion()') === -1) return;
1325

26+
// Extract contract name from the file
27+
const contractNameMatch = src.match(/contract\s+(\w+)/);
28+
if (!contractNameMatch) return;
29+
30+
const contractName = contractNameMatch[1];
31+
32+
// Only update if this contract is in the list to bump
33+
if (!contractsToBump.includes(contractName)) {
34+
console.log(`Skipping ${contractName} - not in bump list`);
35+
return;
36+
}
37+
1438
const match = src.match(versionRegex);
1539
if (match) {
1640
const oldVersion = match[1];
41+
const versionParts = oldVersion.split('.');
42+
const patch = parseInt(versionParts[2]) + 1;
43+
const newVersion = `${versionParts[0]}.${versionParts[1]}.${patch}`;
44+
1745
console.log(`Updating version in: ${srcPath} (${oldVersion} -> ${newVersion})`);
1846
const updatedSrc = src.replace(versionRegex, `version = "${newVersion}";`);
1947
writeSync(srcPath, updatedSrc);
@@ -26,4 +54,4 @@ async function main() {
2654
main().catch(e => {
2755
console.error(e);
2856
process.exit(1);
29-
});
57+
});

0 commit comments

Comments
 (0)