Skip to content

Commit 0cef8b5

Browse files
committed
spanner support
1 parent 6af6d5c commit 0cef8b5

File tree

3 files changed

+228
-3
lines changed

3 files changed

+228
-3
lines changed

.github/actions/setup-python/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ inputs:
55
python-version:
66
description: "Python version to use"
77
required: false
8-
default: "3.12" # PYTHON_VER
8+
default: "3.12" # PY_VER
99
workspace-path:
1010
description: "The directory path to store test results"
1111
required: false

.github/workflows/mysql.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ on:
1111
workflow_dispatch: {}
1212

1313
env:
14-
RUST_VERSION: "1.89"
15-
PYTHON_VERSION: "3.12"
14+
RUST_VERSION: "1.89" # RUST_VER
15+
PYTHON_VERSION: "3.12" # PY_VER
1616

1717
jobs:
1818
build-and-test-mysql:

.github/workflows/spanner.yml

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
name: Spanner Build, Test, and Push
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize]
6+
push:
7+
branches:
8+
- master
9+
tags:
10+
- "**"
11+
workflow_dispatch: {}
12+
13+
env:
14+
RUST_VERSION: "1.89" # RUST_VER
15+
PYTHON_VERSION: "3.12" # PY_VER
16+
17+
jobs:
18+
build-and-test-spanner:
19+
runs-on: ubuntu-latest
20+
21+
services:
22+
spanner-emulator:
23+
image: gcr.io/cloud-spanner-emulator/emulator:1.4.0
24+
# expose the emulator port used in your scripts (adjust if your scripts expect other ports)
25+
ports:
26+
- 9020:9020
27+
options: >-
28+
--health-cmd="nc -z 127.0.0.1 9020 || exit 1"
29+
--health-interval=10s
30+
--health-timeout=5s
31+
--health-retries=10
32+
33+
env:
34+
# The code expects a spanner URL like:
35+
SYNC_SYNCSTORAGE__DATABASE_URL: spanner://projects/test-project/instances/test-instance/databases/test-database
36+
SYNC_SYNCSTORAGE__SPANNER_EMULATOR_HOST: 127.0.0.1:9020
37+
RUST_BACKTRACE: 1
38+
RUST_TEST_THREADS: 1
39+
40+
steps:
41+
- uses: actions/checkout@v6
42+
43+
- uses: ./.github/actions/setup-rust
44+
with:
45+
workspace-path: workflow/test-results
46+
47+
- uses: ./.github/actions/setup-python
48+
with:
49+
workspace-path: workflow/test-results
50+
51+
- name: Create version.json
52+
run: |
53+
printf '{"commit":"%s","version":"%s","source":"https://github.com/%s/%s","build":"%s"}\n' \
54+
"${{ github.sha }}" \
55+
"${{ github.ref_name }}" \
56+
"${{ github.repository_owner }}" \
57+
"${{ github.event.repository.name }}" \
58+
"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
59+
> syncserver/version.json
60+
61+
- name: Install test dependencies
62+
run: cargo install --locked cargo-nextest cargo-llvm-cov
63+
64+
- name: Build workspace (spanner feature)
65+
run: |
66+
# Build with the spanner feature so any compile-time issues surface early
67+
cargo build --workspace --no-default-features --features=syncstorage-db/spanner --features=py_verifier
68+
69+
- name: Wait for Spanner emulator to be ready
70+
run: |
71+
for i in {1..20}; do
72+
if nc -z 127.0.0.1 9020; then
73+
echo "Spanner emulator reachable on 127.0.0.1:9020"
74+
break
75+
fi
76+
echo "Waiting for Spanner emulator..."
77+
sleep 2
78+
done
79+
if ! nc -z 127.0.0.1 9020; then
80+
echo "ERROR: Cannot connect to Spanner emulator at 127.0.0.1:9020. Terminating."
81+
exit 1
82+
fi
83+
84+
- name: Setup Spanner schema & instance (prepare-spanner.sh)
85+
env:
86+
SYNC_SYNCSTORAGE__DATABASE_URL: spanner://projects/test-project/instances/test-instance/databases/test-database
87+
SYNC_SYNCSTORAGE__SPANNER_EMULATOR_HOST: 127.0.0.1:9020
88+
run: |
89+
# your repo has scripts/prepare-spanner.sh in CircleCI — re-use it here
90+
scripts/prepare-spanner.sh
91+
92+
- name: Run Spanner unit tests with coverage
93+
env:
94+
SYNC_SYNCSTORAGE__DATABASE_URL: spanner://projects/test-project/instances/test-instance/databases/test-database
95+
SYNC_SYNCSTORAGE__SPANNER_EMULATOR_HOST: 127.0.0.1:9020
96+
RUST_TEST_THREADS: 1
97+
run: make spanner_test_with_coverage
98+
99+
- name: Upload test results
100+
if: always()
101+
uses: actions/upload-artifact@v6
102+
with:
103+
name: spanner-test-results
104+
path: workflow/test-results/
105+
106+
# Upload to GCS on master
107+
- name: Authenticate to Google Cloud
108+
if: github.ref == 'refs/heads/master' && env.GCP_AUTH_KEY != ''
109+
env:
110+
GCP_AUTH_KEY: ${{ secrets.ETE_GCLOUD_SERVICE_KEY }}
111+
uses: google-github-actions/auth@v3
112+
with:
113+
credentials_json: ${{ secrets.ETE_GCLOUD_SERVICE_KEY }}
114+
115+
- name: Upload JUnit results to GCS
116+
if: github.ref == 'refs/heads/master' && env.GCP_AUTH_KEY != ''
117+
env:
118+
GCP_AUTH_KEY: ${{ secrets.ETE_GCLOUD_SERVICE_KEY }}
119+
uses: google-github-actions/upload-cloud-storage@v2
120+
with:
121+
path: workflow/test-results
122+
destination: ecosystem-test-eng-metrics/syncstorage-rs/junit
123+
glob: "*.xml"
124+
parent: false
125+
process_gcloudignore: false
126+
127+
- name: Upload coverage results to GCS
128+
if: github.ref == 'refs/heads/master' && env.GCP_AUTH_KEY != ''
129+
env:
130+
GCP_AUTH_KEY: ${{ secrets.ETE_GCLOUD_SERVICE_KEY }}
131+
uses: google-github-actions/upload-cloud-storage@v2
132+
with:
133+
path: workflow/test-results
134+
destination: ecosystem-test-eng-metrics/syncstorage-rs/coverage
135+
glob: "*.json"
136+
parent: false
137+
process_gcloudignore: false
138+
139+
build-spanner-image:
140+
runs-on: ubuntu-latest
141+
needs: build-and-test-spanner
142+
143+
steps:
144+
- uses: actions/checkout@v6
145+
146+
- name: Create version.json
147+
run: |
148+
printf '{"commit":"%s","version":"%s","source":"https://github.com/%s/%s","build":"%s"}\n' \
149+
"${{ github.sha }}" \
150+
"${{ github.ref_name }}" \
151+
"${{ github.repository_owner }}" \
152+
"${{ github.event.repository.name }}" \
153+
"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
154+
> syncserver/version.json
155+
156+
- name: Set up Docker Buildx
157+
uses: docker/setup-buildx-action@v3
158+
159+
- name: Build Spanner Docker image (local artifact)
160+
uses: docker/build-push-action@v6
161+
with:
162+
context: .
163+
push: false
164+
tags: app:build
165+
build-args: |
166+
SYNCSTORAGE_DATABASE_BACKEND=spanner
167+
MYSQLCLIENT_PKG=libmysqlclient-dev
168+
outputs: type=docker,dest=/tmp/spanner-image.tar
169+
cache-from: type=gha
170+
cache-to: type=gha,mode=max
171+
172+
- name: Upload Docker image artifact
173+
uses: actions/upload-artifact@v6
174+
with:
175+
name: spanner-docker-image
176+
path: /tmp/spanner-image.tar
177+
retention-days: 1
178+
179+
spanner-e2e-tests:
180+
runs-on: ubuntu-latest
181+
needs: build-spanner-image
182+
183+
steps:
184+
- uses: actions/checkout@v6
185+
186+
- name: Download Docker image
187+
uses: actions/download-artifact@v6
188+
with:
189+
name: spanner-docker-image
190+
path: /tmp
191+
192+
- name: Load Docker image
193+
run: docker load --input /tmp/spanner-image.tar
194+
195+
- name: Create test results directory
196+
run: mkdir -p workflow/test-results
197+
198+
- name: Run Spanner e2e tests
199+
run: make docker_run_spanner_e2e_tests
200+
env:
201+
SYNCSTORAGE_RS_IMAGE: app:build
202+
203+
- name: Upload e2e test results
204+
if: always()
205+
uses: actions/upload-artifact@v6
206+
with:
207+
name: spanner-e2e-test-results
208+
path: workflow/test-results/
209+
210+
# Upload e2e test results to GCS on master
211+
- name: Authenticate to Google Cloud
212+
if: github.ref == 'refs/heads/master' && secrets.ETE_GCLOUD_SERVICE_KEY != ''
213+
uses: google-github-actions/auth@v3
214+
with:
215+
credentials_json: ${{ secrets.ETE_GCLOUD_SERVICE_KEY }}
216+
217+
- name: Upload e2e test results to GCS
218+
if: github.ref == 'refs/heads/master' && secrets.ETE_GCLOUD_SERVICE_KEY != ''
219+
uses: google-github-actions/upload-cloud-storage@v2
220+
with:
221+
path: workflow/test-results
222+
destination: ecosystem-test-eng-metrics/syncstorage-rs/junit
223+
glob: "*.xml"
224+
parent: false
225+
process_gcloudignore: false

0 commit comments

Comments
 (0)