Skip to content

Commit aa71ce2

Browse files
authored
Deployment: Improve version management (#789)
* base implementation * modify make salt * refactor prefix -> suffix * write version in env/files * add version and fix env files * add suffix separation (it mimics testnet deployments) * fix makeSalt to work correctly in all current cases * add legacy support to makeSalt * fix preview with legacy * simplify and double-check correct behavior * adapt PoolHooks to BaseDeployer * add pharos * fix imports * remove warnings * add test create address vs preview address * correctness * fix teg env CI job * ensure version length * fix comment * use constant for the version
1 parent 39310c0 commit aa71ce2

35 files changed

+1838
-834
lines changed

.github/ci-scripts/compute-env-tags.js

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*
1313
* Tag format: deploy-${environment}-${version}-${shortSha}
1414
* - environment: from `network.environment` (e.g. mainnet, testnet)
15-
* - version: from deploymentInfo["deploy:protocol"].version
15+
* - version: highest semver found across all contracts[*].version in the env file
1616
* - shortSha: first 7 chars of the deployment gitCommit
1717
*
1818
* The tag points directly to the deployment commit SHA referenced in the env file,
@@ -73,24 +73,28 @@ function extractTagInfo(filePath) {
7373
return [];
7474
}
7575

76+
// Determine the version from the highest version found across all contracts
77+
const version = findHighestContractVersion(chain.contracts);
78+
7679
const results = [];
7780

78-
// Look for deploy:protocol.version
81+
// Look for deploy:protocol gitCommit
7982
const protocolDeploy = deploymentInfo["deploy:protocol"];
8083
if (protocolDeploy?.gitCommit) {
8184
results.push({
8285
environment,
83-
version: protocolDeploy.version || null,
86+
version,
8487
gitCommit: protocolDeploy.gitCommit,
8588
});
8689
}
8790

88-
// Fallback: check any deploymentInfo entry for gitCommit
89-
for (const value of Object.values(deploymentInfo)) {
91+
// Fallback: check any other deploymentInfo entry for gitCommit
92+
for (const [key, value] of Object.entries(deploymentInfo)) {
93+
if (key === "deploy:protocol") continue;
9094
if (value?.gitCommit) {
9195
results.push({
9296
environment,
93-
version: value.version || null,
97+
version,
9498
gitCommit: value.gitCommit,
9599
});
96100
}
@@ -119,6 +123,56 @@ function generateTimestamp() {
119123
return `${year}${month}${day}-${hours}${minutes}${seconds}`;
120124
}
121125

126+
/**
127+
* Parses a version string into its numeric components.
128+
* Supports formats: "v3.1.0", "v3.1", "v3", "3.1.0", "3.1", "3" (optional 'v' prefix)
129+
* @param {string} versionStr - Version string to parse
130+
* @returns {{ major: number, minor: number, patch: number, original: string } | null}
131+
*/
132+
function parseVersion(versionStr) {
133+
if (!versionStr || typeof versionStr !== "string") return null;
134+
const cleaned = versionStr.replace(/^v/i, "");
135+
const parts = cleaned.split(".").map((p) => parseInt(p, 10));
136+
if (parts.length === 0 || parts.some(isNaN)) return null;
137+
return {
138+
major: parts[0] || 0,
139+
minor: parts[1] || 0,
140+
patch: parts[2] || 0,
141+
original: versionStr,
142+
};
143+
}
144+
145+
/**
146+
* Compares two parsed versions. Returns positive if a > b, negative if a < b, 0 if equal.
147+
* @param {{ major: number, minor: number, patch: number }} a
148+
* @param {{ major: number, minor: number, patch: number }} b
149+
* @returns {number}
150+
*/
151+
function compareVersions(a, b) {
152+
if (a.major !== b.major) return a.major - b.major;
153+
if (a.minor !== b.minor) return a.minor - b.minor;
154+
return a.patch - b.patch;
155+
}
156+
157+
/**
158+
* Finds the highest version across all contracts in the env file.
159+
* @param {Object} contracts - The contracts object from the env JSON
160+
* @returns {string|null} The highest version string found, or null if none
161+
*/
162+
function findHighestContractVersion(contracts) {
163+
if (!contracts || typeof contracts !== "object") return null;
164+
let highest = null;
165+
for (const contract of Object.values(contracts)) {
166+
if (!contract?.version) continue;
167+
const parsed = parseVersion(contract.version);
168+
if (!parsed) continue;
169+
if (!highest || compareVersions(parsed, highest) > 0) {
170+
highest = parsed;
171+
}
172+
}
173+
return highest?.original || null;
174+
}
175+
122176
/**
123177
* Sanitizes a version string for use in a git tag name
124178
* @param {string} version - Version string (e.g., "v3.1", "test-v3.0.1")

.github/workflows/deploy.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ on:
66
- ".github/workflows/deploy.yml"
77
workflow_dispatch:
88
inputs:
9-
version:
10-
description: "Deployment version (e.g. v3.1.5) - if not provided, the job will generate a unique version number"
9+
suffix:
10+
description: "Salt suffix for isolated deployments (e.g. PR-123). Leave empty for canonical versioned addresses."
1111
required: false
1212
type: string
1313
default: "TEST"
@@ -50,18 +50,18 @@ jobs:
5050
id: set-vars
5151
run: |
5252
if [ "${{ github.event_name }}" = "pull_request" ]; then
53-
echo "version=PR-${{ github.run_number }}-${{ github.sha }}" >> $GITHUB_OUTPUT
53+
echo "suffix=PR-${{ github.run_number }}-${{ github.sha }}" >> $GITHUB_OUTPUT
5454
echo "dry=--dry-run" >> $GITHUB_OUTPUT
5555
else
56-
if [ "${{ github.event.inputs.version }}" = "TEST" ]; then
57-
echo "version=TEST-${{ github.run_number }}-${{ github.sha }}" >> $GITHUB_OUTPUT
56+
if [ "${{ github.event.inputs.suffix }}" = "TEST" ]; then
57+
echo "suffix=TEST-${{ github.run_number }}-${{ github.sha }}" >> $GITHUB_OUTPUT
5858
else
59-
echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
59+
echo "suffix=${{ github.event.inputs.suffix }}" >> $GITHUB_OUTPUT
6060
fi
6161
echo "dry=" >> $GITHUB_OUTPUT
6262
fi
6363
- name: Deploying all testnets
6464
env:
65-
VERSION: ${{ steps.set-vars.outputs.version }}
65+
SUFFIX: ${{ steps.set-vars.outputs.suffix }}
6666
run: |
6767
python3 script/deploy/deploy.py ${{ steps.set-vars.outputs.dry }} deploy:testnets

0 commit comments

Comments
 (0)