Commit 23dd85a4 authored by refcell.eth's avatar refcell.eth Committed by GitHub

feat(ops): Consolidate Version Control (#8920)

* feat(ops): consolidate version control

* fix: remove added slitherrc copy

* fix: Makefile geth install target

* fix: remove other redundant cat commands

* fix: rabbit's suggestion
parent 393e6088
71d8ea5923571f33c7aab9ee6e0d1f9a348bd6be
...@@ -201,6 +201,6 @@ install-geth: ...@@ -201,6 +201,6 @@ install-geth:
./ops/scripts/geth-version-checker.sh && \ ./ops/scripts/geth-version-checker.sh && \
(echo "Geth versions match, not installing geth..."; true) || \ (echo "Geth versions match, not installing geth..."; true) || \
(echo "Versions do not match, installing geth!"; \ (echo "Versions do not match, installing geth!"; \
go install -v github.com/ethereum/go-ethereum/cmd/geth@$(shell cat .gethrc); \ go install -v github.com/ethereum/go-ethereum/cmd/geth@$(shell jq -r .geth < versions.json); \
echo "Installed geth!"; true) echo "Installed geth!"; true)
.PHONY: install-geth .PHONY: install-geth
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"os" "os"
"os/exec" "os/exec"
"path" "path"
...@@ -151,13 +152,12 @@ func genContractBindings(logger log.Logger, monorepoRootPath, abiFilePath, bytec ...@@ -151,13 +152,12 @@ func genContractBindings(logger log.Logger, monorepoRootPath, abiFilePath, bytec
abigenVersion := bytes.Trim(versionBuf.Bytes(), "\n") abigenVersion := bytes.Trim(versionBuf.Bytes(), "\n")
// Fetch expected abigen version (format: vX.Y.Z) // Fetch expected abigen version (format: vX.Y.Z)
expectedAbigenVersion, err := os.ReadFile(path.Join(monorepoRootPath, ".abigenrc")) expectedAbigenVersion, err := readExpectedAbigenVersion(monorepoRootPath)
if err != nil { if err != nil {
return fmt.Errorf("error reading .abigenrc file: %w", err) return fmt.Errorf("error fetching the expected abigen version: %w", err)
} }
expectedAbigenVersion = bytes.Trim(expectedAbigenVersion, "\n")[1:]
if !bytes.Contains(abigenVersion, expectedAbigenVersion) { if !bytes.Contains(abigenVersion, []byte(expectedAbigenVersion)) {
return fmt.Errorf("abigen version mismatch, expected %s, got %s. Please run `pnpm install:abigen` in the monorepo root", expectedAbigenVersion, abigenVersion) return fmt.Errorf("abigen version mismatch, expected %s, got %s. Please run `pnpm install:abigen` in the monorepo root", expectedAbigenVersion, abigenVersion)
} }
} else { } else {
...@@ -188,3 +188,42 @@ func genContractBindings(logger log.Logger, monorepoRootPath, abiFilePath, bytec ...@@ -188,3 +188,42 @@ func genContractBindings(logger log.Logger, monorepoRootPath, abiFilePath, bytec
return nil return nil
} }
// Versions is a struct for holding the versions of the tools used in the monorepo
type Versions struct {
Abigen string `json:"abigen"`
Foundry string `json:"foundry"`
Geth string `json:"geth"`
Nvm string `json:"nvm"`
Slither string `json:"slither"`
Kontrol string `json:"kontrol"`
}
// readExpectedAbigenVersion reads the expected abigen version from the monorepo's
// versions.json file. This function will remove the 'v' prefix from the version
// string.
//
// Parameters:
// - monorepoRootPath: The path to the monorepo's root directory.
//
// Returns:
// - The expected abigen version.
// - An error if the versions.json file cannot be read or parsed, nil otherwise.
func readExpectedAbigenVersion(monorepoRootPath string) (string, error) {
// Open the version control file
jsonFile, err := os.Open(path.Join(monorepoRootPath, "versions.json"))
if err != nil {
return "", fmt.Errorf("error reading versions.json file: %w", err)
}
defer jsonFile.Close()
// Parse the version control file
byteValue, _ := io.ReadAll(jsonFile)
var versions Versions
if err := json.Unmarshal(byteValue, &versions); err != nil {
return "", fmt.Errorf("error parsing versions.json file: %w", err)
}
// Trim the 'v' prefix from the version string
return strings.Trim(versions.Abigen, "v"), nil
}
package bindgen
import (
"encoding/json"
"os"
"path"
"testing"
"github.com/stretchr/testify/require"
)
func TestReadExpectedAbigenVersion(t *testing.T) {
// Create a temporary directory for the version control file.
tmpDir := path.Join(os.TempDir(), "version-tests")
defer os.RemoveAll(tmpDir)
require.NoError(t, os.MkdirAll(tmpDir, 0755))
// Create a temporary version control file.
versionFile := path.Join(tmpDir, "versions.json")
versions := Versions{Abigen: "v1.2.3"}
// Marshal the versions to JSON.
versionsJSON, err := json.Marshal(versions)
require.NoError(t, err)
// Write the JSON to the version control file.
require.NoError(t, os.WriteFile(versionFile, versionsJSON, 0644))
// Read the expected version from the version control file.
// The read version should not have a "v" prefix.
expectedVersion, err := readExpectedAbigenVersion(tmpDir)
require.NoError(t, err)
require.Equal(t, expectedVersion, "1.2.3")
}
...@@ -24,7 +24,7 @@ RUN source $HOME/.profile && cargo install svm-rs ...@@ -24,7 +24,7 @@ RUN source $HOME/.profile && cargo install svm-rs
# Only diff from upstream docker image is this clone instead # Only diff from upstream docker image is this clone instead
# of COPY. We select a specific commit to use. # of COPY. We select a specific commit to use.
COPY ./.foundryrc ./.foundryrc COPY ./versions.json ./versions.json
COPY ./ops/scripts/install-foundry.sh ./install-foundry.sh COPY ./ops/scripts/install-foundry.sh ./install-foundry.sh
RUN curl -L https://foundry.paradigm.xyz | bash RUN curl -L https://foundry.paradigm.xyz | bash
...@@ -49,12 +49,10 @@ RUN curl -sL https://go.dev/dl/go$GO_VERSION.linux-amd64.tar.gz -o go$GO_VERSION ...@@ -49,12 +49,10 @@ RUN curl -sL https://go.dev/dl/go$GO_VERSION.linux-amd64.tar.gz -o go$GO_VERSION
ENV GOPATH=/go ENV GOPATH=/go
ENV PATH=/usr/local/go/bin:$GOPATH/bin:$PATH ENV PATH=/usr/local/go/bin:$GOPATH/bin:$PATH
# Install the specific version of abigen from .abigenrc # Install the specific version of abigen and geth from version control
COPY ./.abigenrc ./.abigenrc COPY ./versions.json ./versions.json
RUN go install github.com/ethereum/go-ethereum/cmd/abigen@$(cat .abigenrc) RUN go install github.com/ethereum/go-ethereum/cmd/abigen@$(jq -r .abigen < versions.json)
RUN go install github.com/ethereum/go-ethereum/cmd/geth@$(jq -r .geth < versions.json)
COPY ./.gethrc ./.gethrc
RUN go install github.com/ethereum/go-ethereum/cmd/geth@$(cat .gethrc)
RUN go install gotest.tools/gotestsum@latest RUN go install gotest.tools/gotestsum@latest
RUN go install github.com/vektra/mockery/v2@v2.28.1 RUN go install github.com/vektra/mockery/v2@v2.28.1
...@@ -91,8 +89,8 @@ COPY --from=rust-build /root/.foundry/bin/anvil /usr/local/bin/anvil ...@@ -91,8 +89,8 @@ COPY --from=rust-build /root/.foundry/bin/anvil /usr/local/bin/anvil
COPY --from=echidna-test /usr/local/bin/echidna-test /usr/local/bin/echidna-test COPY --from=echidna-test /usr/local/bin/echidna-test /usr/local/bin/echidna-test
COPY ./.slitherrc ./.slitherrc
COPY .nvmrc .nvmrc COPY .nvmrc .nvmrc
COPY ./versions.json ./versions.json
ENV NODE_MAJOR=20 ENV NODE_MAJOR=20
...@@ -110,7 +108,7 @@ RUN /bin/sh -c set -eux; \ ...@@ -110,7 +108,7 @@ RUN /bin/sh -c set -eux; \
apt-get install -y nodejs docker-ce-cli; \ apt-get install -y nodejs docker-ce-cli; \
ln -s /usr/local/go/bin/gofmt /usr/local/bin/gofmt; \ ln -s /usr/local/go/bin/gofmt /usr/local/bin/gofmt; \
npm i -g depcheck; \ npm i -g depcheck; \
pip install slither-analyzer==$(cat .slitherrc) capstone pyelftools; \ pip install slither-analyzer==$(jq -r .slither < versions.json) capstone pyelftools; \
curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/master/install.sh | bash; \ curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/master/install.sh | bash; \
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
rm -rf /var/lib/apt/lists/*; \ rm -rf /var/lib/apt/lists/*; \
......
* *
!/.foundryrc
!/.abigenrc
!/.gethrc
!/.nvmrc !/.nvmrc
!/.slitherrc !/versions.json
!/ops/scripts/install-foundry.sh !/ops/scripts/install-foundry.sh
#!/bin/bash #!/bin/bash
SCRIPTS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
MONOREPO_DIR=$(cd "$SCRIPTS_DIR/../../" && pwd)
# Extract the version from the geth command output # Extract the version from the geth command output
GETH_VERSION="v$(geth version | grep '^Version:' | awk '{print $2}')" GETH_VERSION="v$(geth version | grep '^Version:' | awk '{print $2}')"
# Read the version from the .gethrc file # Read the version from the versions file
GETHRC_VERSION=$(cat .gethrc) EXPECTED_GETH_VERSION=$(jq -r .geth < $MONOREPO_DIR/versions.json)
# Check if GETHRC_VERSION contains a '-'. If not, append '-stable'. # Check if EXPECTED_GETH_VERSION contains a '-'. If not, append '-stable'.
if [[ $GETHRC_VERSION != *-* ]]; then if [[ $EXPECTED_GETH_VERSION != *-* ]]; then
GETHRC_VERSION="${GETHRC_VERSION}-stable" EXPECTED_GETH_VERSION="${EXPECTED_GETH_VERSION}-stable"
fi fi
# Compare the versions # Compare the versions
if [[ "$GETH_VERSION" == "$GETHRC_VERSION" ]]; then if [[ "$GETH_VERSION" == "$EXPECTED_GETH_VERSION" ]]; then
echo "Geth version $GETH_VERSION is correct!" echo "Geth version $GETH_VERSION is correct!"
exit 0 exit 0
else else
echo "Geth version does not match!" echo "Geth version does not match!"
echo "geth version: $GETH_VERSION" echo "Local geth version: $GETH_VERSION"
echo ".gethrc version: $GETHRC_VERSION" echo "Expected geth version: $EXPECTED_GETH_VERSION"
exit 1 exit 1
fi fi
...@@ -2,10 +2,13 @@ ...@@ -2,10 +2,13 @@
set -e set -e
# Grab the `.foundryrc` commit hash. SCRIPTS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
SHA=$(cat ./.foundryrc) MONOREPO_DIR=$(cd "$SCRIPTS_DIR/../../" && pwd)
# Check if there is a nightly tag corresponding to the `.foundryrc` commit hash # Grab the foundry commit hash.
SHA=$(jq -r .foundry < $MONOREPO_DIR/versions.json)
# Check if there is a nightly tag corresponding to the commit hash
TAG="nightly-$SHA" TAG="nightly-$SHA"
# If the foundry repository exists and a branch is checked out, we need to abort # If the foundry repository exists and a branch is checked out, we need to abort
...@@ -42,3 +45,5 @@ fi ...@@ -42,3 +45,5 @@ fi
# Remove the temporary foundry repo; Used just for checking the nightly tag's existence. # Remove the temporary foundry repo; Used just for checking the nightly tag's existence.
rm -rf "$TMP_DIR" rm -rf "$TMP_DIR"
echo "Removed tempdir @ $TMP_DIR" echo "Removed tempdir @ $TMP_DIR"
...@@ -34,14 +34,14 @@ ...@@ -34,14 +34,14 @@
"release:version": "changeset version && pnpm install --lockfile-only", "release:version": "changeset version && pnpm install --lockfile-only",
"install:foundry": "curl -L https://foundry.paradigm.xyz | bash && pnpm update:foundry", "install:foundry": "curl -L https://foundry.paradigm.xyz | bash && pnpm update:foundry",
"update:foundry": "bash ./ops/scripts/install-foundry.sh", "update:foundry": "bash ./ops/scripts/install-foundry.sh",
"install:abigen": "go install github.com/ethereum/go-ethereum/cmd/abigen@$(cat .abigenrc)", "install:abigen": "go install github.com/ethereum/go-ethereum/cmd/abigen@$(jq -r .abigen < versions.json)",
"print:abigen": "abigen --version | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' -e 's/ /./g' -e 's/^/v/'", "print:abigen": "abigen --version | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' -e 's/ /./g' -e 's/^/v/'",
"check:abigen": "[[ $(abigen --version | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' -e 's/ /./g' -e 's/^/v/') = $(cat .abigenrc) ]] && echo '✓ abigen versions match' || (echo '✗ abigen version mismatch. Run `pnpm upgrade:abigen` to upgrade.' && exit 1)", "check:abigen": "[[ $(pnpm -s print:abigen) = $(cat versions.json | jq -r '.abigen') ]] && echo '✓ abigen versions match' || (echo '✗ abigen version mismatch. Run `pnpm upgrade:abigen` to upgrade.' && exit 1)",
"upgrade:abigen": "abigen --version | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' -e 's/ /./g' -e 's/^/v/' > .abigenrc", "upgrade:abigen": "jq '.abigen = $v' --arg v $(pnpm -s print:abigen) <<<$(cat versions.json) > versions.json",
"install:slither": "pip3 install slither-analyzer==$(cat .slitherrc)", "install:slither": "pip3 install slither-analyzer==$(jq -r .slither < versions.json)",
"print:slither": "slither --version", "print:slither": "slither --version",
"check:slither": "[[ $(slither --version) = $(cat .slitherrc) ]] && echo '✓ slither versions match' || (echo '✗ slither version mismatch. Run `pnpm upgrade:slither` to upgrade.' && exit 1)", "check:slither": "[[ $(pnpm -s print:slither) = $(jq -r .slither < versions.json) ]] && echo '✓ slither versions match' || (echo '✗ slither version mismatch. Run `pnpm upgrade:slither` to upgrade.' && exit 1)",
"upgrade:slither": "slither --version > .slitherrc" "upgrade:slither": "jq '.slither = $v' --arg v $(pnpm -s print:slither) <<<$(cat versions.json) > versions.json"
}, },
"devDependencies": { "devDependencies": {
"@babel/eslint-parser": "^7.23.3", "@babel/eslint-parser": "^7.23.3",
......
...@@ -55,7 +55,7 @@ Optimism's smart contracts are written in Solidity and we use [foundry](https:// ...@@ -55,7 +55,7 @@ Optimism's smart contracts are written in Solidity and we use [foundry](https://
1. Make sure to `pnpm install` 1. Make sure to `pnpm install`
1. [foundry](https://getfoundry.sh) 1. [foundry](https://getfoundry.sh)
1. Foundry is built with [rust](https://www.rust-lang.org/tools/install), and this project uses a pinned version of foundry. Install the rust toolchain with `rustup`. 1. Foundry is built with [rust](https://www.rust-lang.org/tools/install), and this project uses a pinned version of foundry. Install the rust toolchain with `rustup`.
1. Make sure to install the version of foundry used by `ci-builder`, defined in the `.foundryrc` file in the root of this repo. Once you have `foundryup` installed, there is a helper to do this: `pnpm install:foundry` 1. Make sure to install the version of foundry used by `ci-builder`, defined in the `versions.json` file in the root of this repo under the `foundry` key. Once you have `foundryup` installed, there is a helper to do this: `pnpm install:foundry`
1. [golang](https://golang.org/doc/install) 1. [golang](https://golang.org/doc/install)
1. [python](https://www.python.org/downloads/) 1. [python](https://www.python.org/downloads/)
......
...@@ -22,7 +22,7 @@ blank_line ...@@ -22,7 +22,7 @@ blank_line
export FOUNDRY_PROFILE=kontrol export FOUNDRY_PROFILE=kontrol
export CONTAINER_NAME=kontrol-tests export CONTAINER_NAME=kontrol-tests
KONTROLRC=$(cat "${WORKSPACE_DIR}/../../.kontrolrc") KONTROLRC=$(jq -r .kontrol < ${WORKSPACE_DIR}/../../versions.json)
export KONTROL_RELEASE=${KONTROLRC} export KONTROL_RELEASE=${KONTROLRC}
......
{
"abigen": "v1.10.25",
"foundry": "71d8ea5923571f33c7aab9ee6e0d1f9a348bd6be",
"geth": "v1.13.4",
"nvm": "v20.9.0",
"slither": "0.10.0",
"kontrol": "0.1.74"
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment