-
Notifications
You must be signed in to change notification settings - Fork 33
200 lines (188 loc) · 8.52 KB
/
main.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# 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 gitsha="${{ github.event.pull_request.head.sha }}"