[core] Protocol Upgrades #3861
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is a main job that handles tests and builds container images. | |
name: Test, build and push artifacts | |
on: | |
workflow_dispatch: | |
push: | |
branches: [main] | |
# OPTIMIZE: We generate new images even on non src code changes, but this cost is okay for now | |
# paths-ignore: | |
# - "docs/**" | |
# - "**.md" | |
pull_request: | |
# paths-ignore: | |
# - "docs/**" | |
# - "**.md" | |
env: | |
# Even though we can test against multiple versions, this one is considered a target version. | |
TARGET_GOLANG_VERSION: "1.20" | |
PROTOC_VERSION: "3.19.4" | |
jobs: | |
test-multiple-go-versions: | |
runs-on: custom-runner | |
strategy: | |
matrix: | |
go: ["1.20"] # As we are relying on generics, we can't go lower than 1.18. | |
fail-fast: false | |
name: Go ${{ matrix.go }} test | |
steps: | |
- uses: actions/checkout@v3 | |
- name: Setup go | |
uses: actions/setup-go@v3 | |
with: | |
go-version: ${{ matrix.go }} | |
- name: Setup Golang caches | |
uses: actions/cache@v3 | |
with: | |
path: | | |
~/.cache/go-build | |
~/go/pkg/mod | |
key: ${{ runner.os }}-golang-${{ matrix.go }}-${{ hashFiles('**/go.sum') }} | |
restore-keys: | | |
${{ runner.os }}-golang-${{ matrix.go }}- | |
- name: Install Protoc | |
uses: arduino/setup-protoc@v1 | |
with: | |
version: ${{ env.PROTOC_VERSION }} | |
repo-token: ${{ secrets.GITHUB_TOKEN }} | |
- name: install cli dependencies | |
run: make install_cli_deps | |
- name: generate protobufs, RPC server, RPC client and mocks | |
run: make protogen_local && make mockgen && make generate_rpc_openapi | |
- name: Create coverage report and run tests | |
# Not utilizing makefile target here to make use of pipefail bash feature. | |
run: | | |
set -euo pipefail | |
GODEBUG=netdns=cgo go test -tags=test -p 1 -json ./... -covermode=count -coverprofile=coverage.out 2>&1 | tee test_results.json | |
- name: Sanitize test results | |
# We're utilizing `tee` above which can capture non-json stdout output so we need to remove non-json lines before additional parsing and submitting it to the external github action. | |
if: ${{ always() && env.TARGET_GOLANG_VERSION == matrix.go }} | |
run: cat test_results.json | jq -c -R 'fromjson? | select(type == "object")' > tmp.json && mv tmp.json test_results.json | |
- name: Output test failures | |
# Makes it easier to find failed tests so no need to scroll through the whole log. | |
if: ${{ failure() && env.TARGET_GOLANG_VERSION == matrix.go }} | |
run: | | |
jq --argjson fail_tests "$(jq -c -r 'select(.Action == "fail") | select(.Test) | .Test' test_results.json | jq -R -s -c -r 'split("\n") | map(select(length>0))')" 'select(.Test as $t | ($fail_tests | arrays)[] | select($t == .)) | select(.Output) | .Output' test_results.json | jq -r | sed ':a;N;$!ba;s/\n\n/\n/g' > test_failures.json | |
cat test_failures.json | |
exit 1 | |
- name: Upload test results | |
if: ${{ always() && env.TARGET_GOLANG_VERSION == matrix.go }} | |
uses: actions/upload-artifact@v3 | |
with: | |
name: test-results | |
path: | | |
test_*.json | |
- name: Annotate tests on GitHub | |
# Only annotate if the test failed on target version to avoid duplicated annotations on GitHub. | |
if: ${{ always() && env.TARGET_GOLANG_VERSION == matrix.go }} | |
uses: guyarb/[email protected] | |
with: | |
test-results: test_results.json | |
- name: Upload coverage to Codecov | |
if: ${{ always() && env.TARGET_GOLANG_VERSION == matrix.go }} | |
uses: codecov/codecov-action@v3 | |
with: | |
files: ./coverage.out | |
# TODO(@okdas): reuse artifacts built by the previous job instead | |
# of going through the build process in container build job again | |
# - figure out how to handle musl/alpine case if we want to support it | |
build-images: | |
runs-on: custom-runner | |
needs: test-multiple-go-versions | |
# Until we have developer environments, we don't need the images built on other that main branches. | |
if: github.ref == 'refs/heads/main' || contains(github.event.pull_request.labels.*.name, 'push-image') || contains(github.event.pull_request.labels.*.name, 'e2e-devnet-test') | |
strategy: | |
matrix: | |
# Build dev & prod images | |
imageType: [dev, prod] | |
osType: [debian] # Protoc maintainers do not supply a binary for alpine, so we either need to build it or use a different version of protoc | |
steps: | |
- uses: actions/checkout@v3 | |
- name: Docker Setup QEMU | |
uses: docker/setup-qemu-action@v2 | |
- name: Docker Setup Buildx | |
uses: docker/setup-buildx-action@v2 | |
- name: Docker Metadata action | |
id: meta | |
uses: docker/metadata-action@v4 | |
env: | |
DOCKER_METADATA_PR_HEAD_SHA: "true" | |
with: | |
images: | | |
ghcr.io/pokt-network/pocket-v1 | |
tags: | | |
type=schedule${{ matrix.imageType == 'dev' && ',suffix=-dev' || '' }} | |
type=semver,pattern={{version}}${{ matrix.imageType == 'dev' && ',suffix=-dev' || '' }} | |
type=semver,pattern={{major}}.{{minor}}${{ matrix.imageType == 'dev' && ',suffix=-dev' || '' }} | |
type=semver,pattern={{major}}${{ matrix.imageType == 'dev' && ',suffix=-dev' || '' }} | |
type=ref,event=branch${{ matrix.imageType == 'dev' && ',suffix=-dev' || '' }} | |
type=ref,event=pr${{ matrix.imageType == 'dev' && ',suffix=-dev' || '' }} | |
type=sha${{ matrix.imageType == 'dev' && ',suffix=-dev' || '' }} | |
type=sha,format=long${{ matrix.imageType == 'dev' && ',suffix=-dev' || '' }} | |
type=raw,value=latest,enable={{is_default_branch}}${{ matrix.imageType == 'dev' && ',suffix=-dev' || '' }} | |
- name: Login to GitHub Container Registry | |
uses: docker/login-action@v2 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Build and push Docker image | |
uses: docker/build-push-action@v3 | |
with: | |
push: true | |
tags: ${{ steps.meta.outputs.tags }} | |
labels: ${{ steps.meta.outputs.labels }} | |
# NB: Uncomment below if arm64 build is needed; arm64 builds are off by default because build times are significant. | |
platforms: linux/amd64 #,linux/arm64 | |
file: build/Dockerfile.${{ matrix.osType }}.${{ matrix.imageType }} | |
cache-from: type=gha | |
cache-to: type=gha,mode=max | |
build-args: | | |
TARGET_GOLANG_VERSION=${{ env.TARGET_GOLANG_VERSION }} | |
# Run e2e tests on devnet if the PR has a label "e2e-devnet-test" | |
e2e-tests: | |
runs-on: custom-runner | |
needs: build-images | |
if: contains(github.event.pull_request.labels.*.name, 'e2e-devnet-test') | |
env: | |
ARGO_HTTP1: true | |
ARGO_SECURE: true | |
ARGO_SERVER: ${{ vars.ARGO_SERVER }} | |
permissions: | |
contents: "read" | |
id-token: "write" | |
steps: | |
- id: "auth" | |
uses: "google-github-actions/auth@v1" | |
with: | |
credentials_json: "${{ secrets.ARGO_WORKFLOW_EXTERNAL }}" | |
- id: "get-credentials" | |
uses: "google-github-actions/get-gke-credentials@v1" | |
with: | |
cluster_name: "nodes-gcp-dev-us-east4-1" | |
location: "us-east4" | |
- id: "install-argo" | |
# mv ./argo-linux-amd64 /usr/local/bin/argo | |
run: | | |
curl -sLO https://github.com/argoproj/argo-workflows/releases/download/v3.4.7/argo-linux-amd64.gz | |
gunzip argo-linux-amd64.gz | |
chmod +x argo-linux-amd64 | |
echo $PATH | |
./argo-linux-amd64 version | |
- id: "wait-for-infra" | |
shell: bash | |
run: | | |
start_time=$(date +%s) # store current time | |
timeout=900 # 15 minute timeout in seconds | |
until ./argo-linux-amd64 template get dev-e2e-tests --namespace=devnet-issue-${{ github.event.pull_request.number }}; do | |
current_time=$(date +%s) | |
elapsed_time=$(( current_time - start_time )) | |
if (( elapsed_time > timeout )); then | |
echo "Timeout of $timeout seconds reached. Exiting..." | |
exit 1 | |
fi | |
echo "Waiting for devnet-issue-${{ github.event.pull_request.number }} to be provisioned..." | |
sleep 5 | |
done | |
- id: "run-e2e-tests" | |
run: | | |
./argo-linux-amd64 submit --wait --log --namespace devnet-issue-${{ github.event.pull_request.number }} --from 'wftmpl/dev-e2e-tests' --parameter tags="~@skip_in_ci" --parameter gitsha="${{ github.event.pull_request.head.sha }}" |