From b91e854974983412e717872c18f06242ba1042c8 Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Sat, 2 Sep 2023 01:20:46 +0800 Subject: [PATCH] CI, build & docker updates rm makefile basic test add chaindata fixture simplify publish workflow --- .dockerignore | 1 + .gitea/workflows/publish.yml | 28 +++++++ .gitea/workflows/tests.yml | 65 +++++++++++++++++ .github/workflows/manual_publish.yml | 35 --------- .github/workflows/on-publish-pr.yml | 73 ------------------- .github/workflows/tests.yml | 37 ---------- Dockerfile | 28 +++---- Makefile | 12 --- docker-compose.yml | 23 ------ fixture/.gitignore | 6 ++ fixture/chaindata/000002.ldb | Bin 0 -> 918 bytes fixture/chaindata/000004.ldb | Bin 0 -> 35872 bytes fixture/chaindata/ancient/bodies.0000.cdat | 0 fixture/chaindata/ancient/bodies.cidx | Bin 0 -> 6 bytes fixture/chaindata/ancient/bodies.meta | 1 + fixture/chaindata/ancient/diffs.0000.rdat | 0 fixture/chaindata/ancient/diffs.meta | 1 + fixture/chaindata/ancient/diffs.ridx | Bin 0 -> 6 bytes fixture/chaindata/ancient/hashes.0000.rdat | 0 fixture/chaindata/ancient/hashes.meta | 1 + fixture/chaindata/ancient/hashes.ridx | Bin 0 -> 6 bytes fixture/chaindata/ancient/headers.0000.cdat | 0 fixture/chaindata/ancient/headers.cidx | Bin 0 -> 6 bytes fixture/chaindata/ancient/headers.meta | 1 + fixture/chaindata/ancient/receipts.0000.cdat | 0 fixture/chaindata/ancient/receipts.cidx | Bin 0 -> 6 bytes fixture/chaindata/ancient/receipts.meta | 1 + scripts/request-range.sh | 22 ++++++ startup_script.sh | 2 +- test/ci-chain.json | 16 ++++ test/ci-config.toml | 36 +++++++++ test/compose.yml | 23 ++++++ 32 files changed, 218 insertions(+), 194 deletions(-) create mode 100644 .dockerignore create mode 100644 .gitea/workflows/publish.yml create mode 100644 .gitea/workflows/tests.yml delete mode 100644 .github/workflows/manual_publish.yml delete mode 100644 .github/workflows/on-publish-pr.yml delete mode 100644 .github/workflows/tests.yml delete mode 100644 Makefile delete mode 100644 docker-compose.yml create mode 100644 fixture/.gitignore create mode 100644 fixture/chaindata/000002.ldb create mode 100644 fixture/chaindata/000004.ldb create mode 100644 fixture/chaindata/ancient/bodies.0000.cdat create mode 100644 fixture/chaindata/ancient/bodies.cidx create mode 100644 fixture/chaindata/ancient/bodies.meta create mode 100644 fixture/chaindata/ancient/diffs.0000.rdat create mode 100644 fixture/chaindata/ancient/diffs.meta create mode 100644 fixture/chaindata/ancient/diffs.ridx create mode 100644 fixture/chaindata/ancient/hashes.0000.rdat create mode 100644 fixture/chaindata/ancient/hashes.meta create mode 100644 fixture/chaindata/ancient/hashes.ridx create mode 100644 fixture/chaindata/ancient/headers.0000.cdat create mode 100644 fixture/chaindata/ancient/headers.cidx create mode 100644 fixture/chaindata/ancient/headers.meta create mode 100644 fixture/chaindata/ancient/receipts.0000.cdat create mode 100644 fixture/chaindata/ancient/receipts.cidx create mode 100644 fixture/chaindata/ancient/receipts.meta create mode 100755 scripts/request-range.sh create mode 100644 test/ci-chain.json create mode 100644 test/ci-config.toml create mode 100644 test/compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..191381e --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +.git \ No newline at end of file diff --git a/.gitea/workflows/publish.yml b/.gitea/workflows/publish.yml new file mode 100644 index 0000000..03a3513 --- /dev/null +++ b/.gitea/workflows/publish.yml @@ -0,0 +1,28 @@ +name: Publish Docker image + +on: + release: + types: [published] + +jobs: + docker-build: + name: Run docker build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - id: vars + name: Output SHA and version tag + run: | + echo "sha=${GITHUB_SHA:0:7}" >> $GITHUB_OUTPUT + echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + - name: Build and tag image + run: | + docker build . \ + -t cerc-io/eth-statediff-service \ + -t git.vdb.to/cerc-io/eth-statediff-service/eth-statediff-service:${{steps.vars.outputs.sha}} \ + -t git.vdb.to/cerc-io/eth-statediff-service/eth-statediff-service:${{steps.vars.outputs.tag}} + - name: Push image tags + run: | + echo ${{ secrets.GITEA_PUBLISH_TOKEN }} | docker login https://git.vdb.to -u cerccicd --password-stdin + docker push git.vdb.to/cerc-io/eth-statediff-service/eth-statediff-service:${{steps.vars.outputs.sha}} + docker push git.vdb.to/cerc-io/eth-statediff-service/eth-statediff-service:${{steps.vars.outputs.tag}} diff --git a/.gitea/workflows/tests.yml b/.gitea/workflows/tests.yml new file mode 100644 index 0000000..2515480 --- /dev/null +++ b/.gitea/workflows/tests.yml @@ -0,0 +1,65 @@ +name: Tests + +on: + pull_request: + branches: '*' + push: + branches: + - main + - ci-test + workflow_call: + +# Needed until we can incorporate docker startup into the executor container +env: + DOCKER_HOST: unix:///var/run/dind.sock + +jobs: + integration-tests: + name: Run integration tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version-file: go.mod + check-latest: true + - name: Run dockerd + run: | + dockerd -H $DOCKER_HOST --userland-proxy=false & + sleep 5 + - name: Run DB container + run: docker compose -f test/compose.yml up --wait + - name: Configure Gitea access + env: + TOKEN: ${{ secrets.CICD_REPO_TOKEN }} + run: | + git config --global url."https://$TOKEN:@git.vdb.to/".insteadOf "https://git.vdb.to/" + - name: Build package + run: go build . + - name: Run server + env: + DATABASE_TYPE: postgres + LEVELDB_PATH: ./fixture/chaindata + LEVELDB_ANCIENT: ./fixture/chaindata/ancient + LOG_FILE_PATH: ./server-log + run: | + ./eth-statediff-service --config ./test/ci-config.toml serve & + + # Run a sanity test against the fixture data + # Complete integration tests are TODO + - name: Run test + run: | + ./scripts/request-range.sh 0 32 || (E=$?; cat ./server-log; exit $E) + + until grep "Finished processing block 32" ./server-log + do sleep 1; done + + count_results() { + query="select count(*) from $1;" + docker exec -e PGPASSWORD=password test-ipld-eth-db-1 \ + psql -tA cerc_testing -U vdbm -c "$query" + } + set -x + [[ "$(count_results eth.header_cids)" = 33 ]] + [[ "$(count_results eth.state_cids)" = 21 ]] + [[ "$(count_results eth.storage_cids)" = 18 ]] diff --git a/.github/workflows/manual_publish.yml b/.github/workflows/manual_publish.yml deleted file mode 100644 index f884a29..0000000 --- a/.github/workflows/manual_publish.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: MANUAL Override Publish from release SHA to TAG -on: - workflow_dispatch: - inputs: - giteaPublishTag: - description: 'Release TAG to publish TO on gitea; e.g. v4.1.5-alpha' - required: true - cercContainerTag: - description: 'Container (truncated!!! SHA) to release-tag FROM' - required: true - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - name: Pull SHA and add release-tag - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Get the version - id: vars - run: | - echo ::set-output name=sha::$(echo ${cercContainerTag:0:7}) - - name: Pull docker image by SHA - run: docker pull git.vdb.to/cerc-io/eth-statediff-service/eth-statediff-service:${{github.event.inputs.cercContainerTag}} - - name: Tag docker image TAG - run: docker tag git.vdb.to/cerc-io/eth-statediff-service/eth-statediff-service:${{github.event.inputs.cercContainerTag}} git.vdb.to/cerc-io/eth-statediff-service/eth-statediff-service:${{github.event.inputs.giteaPublishTag}} - - name: Tag docker image TAG - run: docker tag git.vdb.to/cerc-io/eth-statediff-service/eth-statediff-service:${{github.event.inputs.cercContainerTag}} git.vdb.to/cerc-io/eth-statediff-service/eth-statediff-service:latest - - name: Docker Login - run: echo ${{ secrets.GITEA_TOKEN }} | docker login https://git.vdb.to -u cerccicd --password-stdin - - name: Docker Push Release Tag - run: docker push git.vdb.to/cerc-io/eth-statediff-service/eth-statediff-service:${{github.event.inputs.giteaPublishTag}} - - name: Docker Push LATEST Tag - run: docker push git.vdb.to/cerc-io/eth-statediff-service/eth-statediff-service:latest diff --git a/.github/workflows/on-publish-pr.yml b/.github/workflows/on-publish-pr.yml deleted file mode 100644 index 952be1d..0000000 --- a/.github/workflows/on-publish-pr.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: Publish Docker image -on: - release: - types: [published] - pull_request: -jobs: - pre_job: - # continue-on-error: true # Uncomment once integration is finished - runs-on: ubuntu-latest - # Map a step output to a job output - outputs: - should_skip: ${{ steps.skip_check.outputs.should_skip }} - steps: - - id: skip_check - uses: fkirc/skip-duplicate-actions@v4 - with: - # All of these options are optional, so you can remove them if you are happy with the defaults - concurrent_skipping: "never" - skip_after_successful_duplicate: "true" - do_not_skip: '["workflow_dispatch", "schedule"]' - run-tests: - if: ${{ needs.pre_job.outputs.should_skip != 'true' }} - needs: pre_job - uses: ./.github/workflows/tests.yml - build: - name: Run docker build - runs-on: ubuntu-latest - if: | - always() && - (needs.run-tests.result == 'success' || needs.run-tests.result == 'skipped') && - github.event_name == 'release' - needs: run-tests - steps: - - uses: actions/checkout@v2 - - name: Get the version - id: vars - run: | - echo ::set-output name=sha::$(echo ${GITHUB_SHA:0:7}) - echo ::set-output name=tag::$(echo ${GITHUB_REF#refs/tags/}) - - name: Run docker build - run: make docker-build - - name: Tag docker image - run: docker tag cerc-io/eth-statediff-service git.vdb.to/cerc-io/eth-statediff-service/eth-statediff-service:${{steps.vars.outputs.sha}} - - name: Tag docker image TAG - run: docker tag git.vdb.to/cerc-io/eth-statediff-service/eth-statediff-service:${{steps.vars.outputs.sha}} git.vdb.to/cerc-io/eth-statediff-service/eth-statediff-service:${{steps.vars.outputs.tag}} - - name: Docker Login - run: echo ${{ secrets.GITEA_TOKEN }} | docker login https://git.vdb.to -u cerccicd --password-stdin - - name: Docker Push - run: docker push git.vdb.to/cerc-io/eth-statediff-service/eth-statediff-service:${{steps.vars.outputs.sha}} -# push_to_registries: -# name: Push Docker image to Docker Hub -# runs-on: ubuntu-latest -# if: | -# always() && -# (needs.build.result == 'success') && -# github.event_name == 'release' -# needs: build -# steps: -# - name: Get the version -# id: vars -# run: | -# echo ::set-output name=sha::$(echo ${GITHUB_SHA:0:7}) -# echo ::set-output name=tag::$(echo ${GITHUB_REF#refs/tags/}) -# - name: Docker Login to Github Registry -# run: echo ${{ secrets.GITHUB_TOKEN }} | docker login https://docker.pkg.github.com -u vulcanize --password-stdin -# - name: Docker Pull -# run: docker pull docker.pkg.github.com/cerc-io/eth-statediff-service/eth-statediff-service:${{steps.vars.outputs.sha}} -# - name: Docker Login to Docker Registry -# run: echo ${{ secrets.VULCANIZEJENKINS_PAT }} | docker login -u vulcanizejenkins --password-stdin -# - name: Tag docker image -# run: docker tag docker.pkg.github.com/cerc-io/eth-statediff-service/eth-statediff-service:${{steps.vars.outputs.sha}} cerc-io/eth-statediff-service:${{steps.vars.outputs.tag}} -# - name: Docker Push to Docker Hub -# run: docker push cerc-io/eth-statediff-service:${{steps.vars.outputs.tag}} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml deleted file mode 100644 index 17ed729..0000000 --- a/.github/workflows/tests.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Tests for Geth that are used in multiple jobs. - -on: - workflow_call: - -env: - GOPATH: /tmp/go - -jobs: - build: - name: Run docker build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Run docker build - run: make docker-build - - statediff-unit-test: - name: Run statediff unit tests - runs-on: ubuntu-latest - env: - GO111MODULE: on - steps: - - name: Create GOPATH - run: mkdir -p /tmp/go - - - uses: actions/setup-go@v3 - with: - go-version: ">=1.18.0" - check-latest: true - - - name: Checkout code - uses: actions/checkout@v2 - - - name: Run unit tests - run: | - make test diff --git a/Dockerfile b/Dockerfile index 65a9172..1f98491 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,24 @@ FROM golang:1.19-alpine as builder -RUN apk --update --no-cache add make git g++ linux-headers +RUN apk add --no-cache git gcc musl-dev binutils-gold # DEBUG RUN apk add busybox-extras -# Get and build ipfs-blockchain-watcher -ADD . /go/src/github.com/cerc-io/eth-statediff-service -#RUN git clone https://github.com/cerc-io/eth-statediff-service.git /go/src/github.com/vulcanize/eth-statediff-service +WORKDIR /eth-statediff-service -WORKDIR /go/src/github.com/cerc-io/eth-statediff-service -RUN GO111MODULE=on GCO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o eth-statediff-service . +ARG GIT_VDBTO_TOKEN + +COPY go.mod go.sum ./ +RUN if [ -n "$GIT_VDBTO_TOKEN" ]; then git config --global url."https://$GIT_VDBTO_TOKEN:@git.vdb.to/".insteadOf "https://git.vdb.to/"; fi && \ + go mod download && \ + rm -f ~/.gitconfig +COPY . . + +RUN go build -ldflags '-extldflags "-static"' -o eth-statediff-service . -# app container FROM alpine -ARG USER="vdm" -ARG CONFIG_FILE="./environments/config.toml" +ARG USER="vdbm" ARG EXPOSE_PORT=8545 RUN adduser -Du 5000 $USER adm @@ -27,12 +30,11 @@ USER $USER # chown first so dir is writable # note: using $USER is merged, but not in the stable release yet -COPY --chown=5000:5000 --from=builder /go/src/github.com/cerc-io/eth-statediff-service/$CONFIG_FILE config.toml -COPY --chown=5000:5000 --from=builder /go/src/github.com/cerc-io/eth-statediff-service/startup_script.sh . -COPY --chown=5000:5000 --from=builder /go/src/github.com/cerc-io/eth-statediff-service/environments environments +COPY --chown=5000:5000 --from=builder /eth-statediff-service/startup_script.sh . +COPY --chown=5000:5000 --from=builder /eth-statediff-service/environments environments # keep binaries immutable -COPY --from=builder /go/src/github.com/cerc-io/eth-statediff-service/eth-statediff-service eth-statediff-service +COPY --from=builder /eth-statediff-service/eth-statediff-service eth-statediff-service EXPOSE $EXPOSE_PORT diff --git a/Makefile b/Makefile deleted file mode 100644 index 48bd006..0000000 --- a/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -## Build docker image -.PHONY: docker-build -docker-build: - docker build -t cerc-io/eth-statediff-service . - -.PHONY: test -test: - go test -p 1 ./pkg/... -v - -build: - go fmt ./... - go build diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 74f6334..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,23 +0,0 @@ -version: '3.2' - -services: - eth-statediff-service: - build: - context: ./ - cache_from: - - alpine:latest - - golang:1.16 - dockerfile: ./Dockerfile - args: - USER: "vdbm" - CONFIG_FILE: ./environments/example.toml - EXPOSE_PORT: 8545 - environment: - - VDB_COMMAND=serve - volumes: - - eth-statediff-service-data:/root/.ethereum/ - ports: - - "127.0.0.1:8545:8545" - -volumes: - eth-statediff-service-data: diff --git a/fixture/.gitignore b/fixture/.gitignore new file mode 100644 index 0000000..c95f9f9 --- /dev/null +++ b/fixture/.gitignore @@ -0,0 +1,6 @@ +*/*.log +*/CURRENT* +*/LOCK +*/LOG +*/MANIFEST-* +*/ancient/FLOCK diff --git a/fixture/chaindata/000002.ldb b/fixture/chaindata/000002.ldb new file mode 100644 index 0000000000000000000000000000000000000000..c7bb1f94f98117e2689a22dd14a344f424d036f8 GIT binary patch literal 918 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 t8<+}RfVdWj`+yj<>yvTv`_sX