Skip to content

Commit 419f76b

Browse files
authored
Zh automatic signing releases in ci (#17)
1 parent cf63c46 commit 419f76b

36 files changed

+1883
-3970
lines changed

.dockerignore

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Exclude unnecessary files from Docker build context
2+
.git
3+
.gitignore
4+
.travis.yml
5+
.github
6+
*.md
7+
*.sh
8+
*.go
9+
go.mod
10+
go.sum
11+
bin/
12+
dist/
13+
examples/
14+
scripts/
15+
docs/
16+
*.tf
17+
terraform.tfstate*
18+
.terraform/
19+
.DS_Store
20+
*.log
21+
*.backup
22+
Makefile
23+
GNUmakefile
24+
GORELEASER_GPGSIGNING_PLAN.md
25+
TERRAFORM_BINARY_OPTIMIZATION_PLAN.md
26+
TESTCONTAINERS_*.md
27+
TIDB_*.md
28+
WORKFLOW_OPTIMIZATION_ANALYSIS.md
29+
terraform-registry-manifest.json
30+
VERSION

.github/workflows/main.yml

Lines changed: 158 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,28 @@ jobs:
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]

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@ website/vendor
3535
# Test exclusions
3636
!command/test-fixtures/**/*.tfstate
3737
!command/test-fixtures/**/.terraform/
38+
test-runner

.goreleaser.yml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,35 @@ checksum:
3939
name_template: "{{ .ProjectName }}_{{ .Version }}_SHA256SUMS"
4040
algorithm: sha256
4141
signs:
42-
- artifacts: checksum
42+
- id: checksum
43+
artifacts: checksum
4344
args:
44-
# if you are using this is a GitHub action or some other automated pipeline, you
45-
# need to pass the batch flag to indicate its not interactive.
45+
# Subkey has no passphrase - no --passphrase flag needed
4646
- "--batch"
47+
- "--yes"
48+
- "--no-tty"
49+
- "--pinentry-mode"
50+
- "loopback"
4751
- "--local-user"
4852
- "{{ .Env.GPG_FINGERPRINT }}" # set this environment variable for your signing key
4953
- "--output"
5054
- "${signature}"
5155
- "--detach-sign"
5256
- "${artifact}"
57+
- id: archive
58+
artifacts: archive
59+
args:
60+
- "--batch"
61+
- "--yes"
62+
- "--no-tty"
63+
- "--pinentry-mode"
64+
- "loopback"
65+
- "--local-user"
66+
- "{{ .Env.GPG_FINGERPRINT }}"
67+
- "--output"
68+
- "${signature}"
69+
- "--detach-sign"
70+
- "${artifact}"
5371
release:
5472
# If you want to manually examine the release before its live, uncomment this line:
5573
draft: true

Dockerfile.tiup-playground

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Dockerfile for TiUP Playground container
2+
# This image contains TiUP and can run TiDB Playground inside a container
3+
4+
FROM ubuntu:22.04
5+
6+
# Install dependencies
7+
RUN apt-get update && \
8+
apt-get install -y --no-install-recommends \
9+
curl \
10+
ca-certificates \
11+
mysql-client \
12+
&& rm -rf /var/lib/apt/lists/*
13+
14+
# Install TiUP
15+
RUN curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
16+
17+
# Add TiUP to PATH
18+
ENV PATH="/root/.tiup/bin:${PATH}"
19+
20+
# Update TiUP and playground component
21+
RUN /root/.tiup/bin/tiup update --self && \
22+
/root/.tiup/bin/tiup update playground || true
23+
24+
# Default command runs TiUP Playground
25+
# This will be overridden by testcontainers with specific version and port
26+
CMD ["/root/.tiup/bin/tiup", "playground"]

0 commit comments

Comments
 (0)