7575 - name : Vendor Go dependencies
7676 run : go mod vendor
7777
78+ - name : Set up Docker Buildx
79+ uses : docker/setup-buildx-action@v3
80+
81+ - name : Build and cache TiUP Playground Docker image
82+ uses : docker/build-push-action@v5
83+ with :
84+ context : .
85+ file : ./Dockerfile.tiup-playground
86+ tags : terraform-provider-mysql-tiup-playground:latest
87+ cache-from : type=gha
88+ cache-to : type=gha,mode=max
89+ push : false
90+ load : true
91+
92+ - name : Save TiUP Playground Docker image
93+ run : |
94+ docker save terraform-provider-mysql-tiup-playground:latest | gzip > tiup-playground-image.tar.gz
95+ echo "Image saved: $(du -h tiup-playground-image.tar.gz | cut -f1)"
96+
7897 # Note: Tests now use testcontainers - no mysql-client or Docker Buildx caching needed
7998 # Testcontainers handles container lifecycle and image pulling automatically
99+ # TiUP Playground image is pre-built above and saved as artifact for test jobs
80100
81101 - name : Upload Terraform binary
82102 uses : actions/upload-artifact@v4
@@ -92,6 +112,14 @@ jobs:
92112 path : vendor/
93113 retention-days : 1
94114 compression-level : 6
115+
116+ - name : Upload TiUP Playground Docker image
117+ uses : actions/upload-artifact@v4
118+ with :
119+ name : tiup-playground-image
120+ path : tiup-playground-image.tar.gz
121+ retention-days : 1
122+ compression-level : 6
95123
96124 tests :
97125 runs-on : ubuntu-22.04
@@ -103,43 +131,49 @@ jobs:
103131 # MySQL versions
104132 - db_type : mysql
105133 db_version : " 5.6"
106- docker_image : " mysql: 5.6"
134+ make_target : " test- mysql- 5.6"
107135 - db_type : mysql
108136 db_version : " 5.7"
109- docker_image : " mysql: 5.7"
137+ make_target : " test- mysql- 5.7"
110138 - db_type : mysql
111139 db_version : " 8.0"
112- docker_image : " mysql: 8.0"
140+ make_target : " test- mysql- 8.0"
113141 # Percona versions
114142 - db_type : percona
115143 db_version : " 5.7"
116- docker_image : " percona: 5.7"
144+ make_target : " test- percona- 5.7"
117145 - db_type : percona
118146 db_version : " 8.0"
119- docker_image : " percona: 8.0"
147+ make_target : " test- percona- 8.0"
120148 # MariaDB versions
121149 - db_type : mariadb
122150 db_version : " 10.3"
123- docker_image : " mariadb: 10.3"
151+ make_target : " test- mariadb- 10.3"
124152 - db_type : mariadb
125153 db_version : " 10.8"
126- docker_image : " mariadb: 10.8"
154+ make_target : " test- mariadb- 10.8"
127155 - db_type : mariadb
128156 db_version : " 10.10"
129- docker_image : " mariadb: 10.10"
157+ make_target : " test- mariadb- 10.10"
130158 # TiDB versions - must match env.TIDB_VERSIONS: 6.1.7 6.5.12 7.1.6 7.5.7 8.1.2 8.5.3
131159 - db_type : tidb
132160 db_version : " 6.1.7"
161+ make_target : " test-tidb-6.1.7"
133162 - db_type : tidb
134163 db_version : " 6.5.12"
164+ make_target : " test-tidb-6.5.12"
135165 - db_type : tidb
136166 db_version : " 7.1.6"
167+ make_target : " test-tidb-7.1.6"
137168 - db_type : tidb
138169 db_version : " 7.5.7"
170+ make_target : " test-tidb-7.5.7"
139171 - db_type : tidb
140172 db_version : " 8.1.2"
173+ make_target : " test-tidb-8.1.2"
141174 - db_type : tidb
142175 db_version : " 8.5.3"
176+ make_target : " test-tidb-8.5.3"
143177 steps :
144178 - name : Checkout Git repo
145179 uses : actions/checkout@v4
@@ -169,56 +203,131 @@ jobs:
169203 - name : Set up Docker Buildx
170204 uses : docker/setup-buildx-action@v3
171205
172- - name : Pre-pull Docker images for caching
173- if : matrix.db_type != 'tidb'
174- run : |
175- docker pull ${{ matrix.docker_image }} || true
206+ - name : Download TiUP Playground Docker image
207+ uses : actions/download-artifact@v4
208+ with :
209+ name : tiup-playground-image
210+ path : ./
176211
177- - name : Pre-pull TiDB images for caching
178- if : matrix.db_type == 'tidb'
212+ - name : Load TiUP Playground Docker image
179213 run : |
180- docker pull pingcap/tidb:v${{ matrix.db_version }} || true
181- docker pull pingcap/pd:v${{ matrix.db_version }} || true
182- docker pull pingcap/tikv:v${{ matrix.db_version }} || true
214+ echo "Loading pre-built TiUP Playground Docker image..."
215+ gunzip -c tiup-playground-image.tar.gz | docker load
216+ docker images | grep terraform-provider-mysql-tiup-playground
217+ echo "✓ TiUP Playground image loaded successfully"
183218
184- - name : Run testcontainers tests
219+ # Note: TiUP Playground image is pre-built in prepare-dependencies and loaded here
220+ # This avoids rebuilding the image during each test run
221+ # Testcontainers handles container lifecycle and image pulling automatically
222+
223+ - name : Run testcontainers tests via Makefile
185224 env :
186225 GOFLAGS : -mod=vendor
187226 TF_ACC : 1
188227 GOTOOLCHAIN : auto
189228 run : |
190229 export PATH="${{ github.workspace }}/bin:$PATH"
191- if [ "${{ matrix.db_type }}" == "tidb" ]; then
192- TIDB_VERSION=${{ matrix.db_version }} go test -tags=testcontainers -v ./mysql/... -run WithTestcontainers -timeout=30m
193- else
194- DOCKER_IMAGE=${{ matrix.docker_image }} go test -tags=testcontainers -v ./mysql/... -run WithTestcontainers -timeout=30m
195- fi
196- # DISABLED to figure out GPG signing issue on Github Actions
197- # possibly due to lack of TTY inside docker?
198- # release:
199- # name: Release
200- # needs: [tests]
201- # # Can't use non-semvar for the testing tag
202- # # https://github.com/orgs/goreleaser/discussions/3708
203- # if: ( startsWith( github.ref, 'refs/tags/v' ) ||
204- # startsWith(github.ref, 'refs/tags/v0.0.0-rc') )
205- # runs-on: ubuntu-22.04
206- # steps:
207- # - name: Checkout Git repo
208- # uses: actions/checkout@v4
209-
210- # # Goreleaser
211- # - name: Set up Go
212- # uses: actions/setup-go@v4
213- # - name: Run GoReleaser
214- # uses: goreleaser/goreleaser-action@v6
215- # with:
216- # distribution: goreleaser
217- # version: '~> v2'
218- # # Run goreleaser and ignore non-committed files (downloaded artifacts)
219- # args: release --clean --skip=validate --verbose
220- # env:
221- # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
230+ echo "Running ${{ matrix.db_type }} ${{ matrix.db_version }} tests using Makefile target: ${{ matrix.make_target }}"
231+ make ${{ matrix.make_target }}
232+ release :
233+ name : Release
234+ needs : [tests]
235+ # Can't use non-semvar for the testing tag
236+ # https://github.com/orgs/goreleaser/discussions/3708
237+ if : ( startsWith( github.ref, 'refs/tags/v' ) ||
238+ startsWith(github.ref, 'refs/tags/v0.0.0-rc') )
239+ runs-on : ubuntu-22.04
240+ permissions :
241+ contents : write # Required for creating releases
242+ steps :
243+ - name : Checkout Git repo
244+ uses : actions/checkout@v4
245+ with :
246+ fetch-depth : 0 # Full history needed for changelog
247+
248+ - name : Set up Go
249+ uses : actions/setup-go@v4
250+ with :
251+ go-version-file : go.mod
252+
253+ - name : Import GPG Subkey
254+ env :
255+ GPG_PRIVATE_KEY : ${{ secrets.GPG_PRIVATE_KEY }}
256+ GPG_FINGERPRINT : ${{ secrets.GPG_FINGERPRINT }}
257+ run : |
258+ # Install gnupg2 if not already available
259+ sudo apt-get update && sudo apt-get install -y gnupg2 || true
260+
261+ # Create GPG directory
262+ mkdir -p ~/.gnupg
263+ chmod 700 ~/.gnupg
264+
265+ # Remove any existing gpg.conf to avoid conflicts
266+ rm -f ~/.gnupg/gpg.conf
267+
268+ # Configure GPG for non-interactive use
269+ cat > ~/.gnupg/gpg.conf <<EOF
270+ use-agent
271+ pinentry-mode loopback
272+ EOF
273+
274+ # Configure gpg-agent for loopback pinentry
275+ cat > ~/.gnupg/gpg-agent.conf <<EOF
276+ allow-loopback-pinentry
277+ default-cache-ttl 3600
278+ max-cache-ttl 3600
279+ EOF
280+ chmod 600 ~/.gnupg/gpg-agent.conf
281+
282+ # Kill any existing gpg-agent and start fresh with loopback pinentry
283+ gpgconf --kill gpg-agent 2>/dev/null || true
284+ gpgconf --kill dirmngr 2>/dev/null || true
285+ sleep 1
286+ gpg-agent --daemon --allow-loopback-pinentry > /dev/null 2>&1 || true
287+ sleep 2 # Give gpg-agent time to start
288+
289+ # Import the subkey (no passphrase required)
290+ KEY_FILE=$(mktemp)
291+ echo "$GPG_PRIVATE_KEY" > "$KEY_FILE"
292+ gpg --batch --yes --import "$KEY_FILE"
293+ rm -f "$KEY_FILE"
294+
295+ # Trust the key (required for signing)
296+ # Format: fingerprint:trust-level: (fingerprint must be uppercase, no spaces, no colons)
297+ # Use ultimate trust (6) for the subkey
298+ FINGERPRINT_UPPER=$(echo "$GPG_FINGERPRINT" | tr '[:lower:]' '[:upper:]' | tr -d ' ' | tr -d ':')
299+ echo "$FINGERPRINT_UPPER:6:" | gpg --batch --import-ownertrust
300+
301+ # Verify key is available
302+ gpg --list-secret-keys --keyid-format LONG
303+
304+ # Verify signing works (subkey has no passphrase)
305+ echo "test" | gpg --batch --no-tty --pinentry-mode loopback --sign --local-user "$FINGERPRINT_UPPER" -o /dev/null 2>&1 && echo "✓ Test signing successful" || echo "⚠ Test signing failed"
306+
307+ echo "✓ GPG key imported successfully"
308+
309+ - name : Verify GPG setup before GoReleaser
310+ env :
311+ GPG_FINGERPRINT : ${{ secrets.GPG_FINGERPRINT }}
312+ run : |
313+ echo "Verifying GPG setup..."
314+ echo "GPG_FINGERPRINT length: ${#GPG_FINGERPRINT}"
315+ gpg --list-secret-keys --keyid-format LONG
316+ # Test signing (subkey has no passphrase)
317+ echo "test" | gpg --batch --yes --no-tty --pinentry-mode loopback --local-user "$GPG_FINGERPRINT" --sign -o /tmp/test.sig - 2>&1 && echo "✓ Test signing successful" || echo "⚠ Test signing failed"
318+ rm -f /tmp/test.sig
319+
320+ - name : Run GoReleaser
321+ uses : goreleaser/goreleaser-action@v6
322+ with :
323+ distribution : goreleaser
324+ version : ' ~> v2'
325+ # Run goreleaser and ignore non-committed files (downloaded artifacts)
326+ args : release --clean --skip=validate
327+ env :
328+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
329+ GPG_FINGERPRINT : ${{ secrets.GPG_FINGERPRINT }}
330+ GPG_TTY : $(tty)
222331
223332 # terraform-provider-release:
224333 # needs: [release]
0 commit comments