Zh automatic signing releases in ci #140
Workflow file for this run
This file contains hidden or 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
| name: Main (test, releases) | |
| on: | |
| # # Indicates I want to run this workflow on all branches, PR, and tags | |
| push: | |
| branches: ["master"] | |
| tags: ["*"] | |
| pull_request: | |
| branches: [ "*" ] | |
| # TiDB versions used in tests - single source of truth | |
| # Latest version of each minor series: 6.1.x, 6.5.x, 7.1.x, 7.5.x, 8.1.x, 8.5.x | |
| env: | |
| TIDB_VERSIONS: "6.1.7 6.5.12 7.1.6 7.5.7 8.1.2 8.5.3" | |
| jobs: | |
| lint: | |
| runs-on: ubuntu-22.04 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| command: | |
| - make vet | |
| - make fmtcheck | |
| steps: | |
| - name: Checkout Git repo | |
| uses: actions/checkout@v4 | |
| - name: Running ${{ matrix.command }} | |
| run: ${{ matrix.command }} | |
| prepare-dependencies: | |
| name: Prepare Dependencies | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: Checkout Git repo | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| - name: Validate TiDB versions sync | |
| run: | | |
| # Extract TiDB versions from test matrix and compare with env.TIDB_VERSIONS | |
| EXPECTED_VERSIONS="${{ env.TIDB_VERSIONS }}" | |
| MATRIX_VERSIONS=$(grep -A 20 "db_type: tidb" .github/workflows/main.yml | grep "db_version:" | sed 's/.*db_version: "\([0-9.]*\)".*/\1/' | tr '\n' ' ' | xargs) | |
| echo "Expected versions (from env): $EXPECTED_VERSIONS" | |
| echo "Matrix versions (from workflow): $MATRIX_VERSIONS" | |
| # Check if versions match (simple check - both should contain same versions) | |
| MISSING="" | |
| for version in $EXPECTED_VERSIONS; do | |
| if ! echo "$MATRIX_VERSIONS" | grep -q "$version"; then | |
| MISSING="$MISSING $version" | |
| fi | |
| done | |
| if [ -n "$MISSING" ]; then | |
| echo "ERROR: TiDB versions in env.TIDB_VERSIONS not found in test matrix: $MISSING" | |
| echo "Please ensure test matrix includes tidb entries for all versions in env.TIDB_VERSIONS" | |
| exit 1 | |
| fi | |
| echo "✓ TiDB versions are in sync" | |
| - name: Set up Go | |
| uses: actions/setup-go@v4 | |
| with: | |
| go-version-file: go.mod | |
| - name: Download Terraform | |
| run: | | |
| mkdir -p bin | |
| curl -sfL https://releases.hashicorp.com/terraform/1.5.6/terraform_1.5.6_linux_amd64.zip > bin/terraform.zip | |
| cd bin && unzip terraform.zip && rm terraform.zip && chmod +x terraform | |
| - name: Vendor Go dependencies | |
| run: go mod vendor | |
| # Note: Tests now use testcontainers - no mysql-client or Docker Buildx caching needed | |
| # Testcontainers handles container lifecycle and image pulling automatically | |
| - name: Upload Terraform binary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: terraform-binary | |
| path: bin/terraform | |
| retention-days: 1 | |
| - name: Upload vendor directory | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: vendor-dir | |
| path: vendor/ | |
| retention-days: 1 | |
| compression-level: 6 | |
| tests: | |
| runs-on: ubuntu-22.04 | |
| needs: [prepare-dependencies] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # MySQL versions | |
| - db_type: mysql | |
| db_version: "5.6" | |
| docker_image: "mysql:5.6" | |
| - db_type: mysql | |
| db_version: "5.7" | |
| docker_image: "mysql:5.7" | |
| - db_type: mysql | |
| db_version: "8.0" | |
| docker_image: "mysql:8.0" | |
| # Percona versions | |
| - db_type: percona | |
| db_version: "5.7" | |
| docker_image: "percona:5.7" | |
| - db_type: percona | |
| db_version: "8.0" | |
| docker_image: "percona:8.0" | |
| # MariaDB versions | |
| - db_type: mariadb | |
| db_version: "10.3" | |
| docker_image: "mariadb:10.3" | |
| - db_type: mariadb | |
| db_version: "10.8" | |
| docker_image: "mariadb:10.8" | |
| - db_type: mariadb | |
| db_version: "10.10" | |
| docker_image: "mariadb:10.10" | |
| # 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 | |
| - db_type: tidb | |
| db_version: "6.1.7" | |
| - db_type: tidb | |
| db_version: "6.5.12" | |
| - db_type: tidb | |
| db_version: "7.1.6" | |
| - db_type: tidb | |
| db_version: "7.5.7" | |
| - db_type: tidb | |
| db_version: "8.1.2" | |
| - db_type: tidb | |
| db_version: "8.5.3" | |
| steps: | |
| - name: Checkout Git repo | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| - name: Set up Go | |
| uses: actions/setup-go@v4 | |
| with: | |
| go-version-file: go.mod | |
| - name: Download Terraform binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: terraform-binary | |
| path: bin/ | |
| - name: Download vendor directory | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: vendor-dir | |
| path: vendor/ | |
| - name: Make Terraform executable | |
| run: chmod +x bin/terraform | |
| # Note: Docker Buildx not needed - testcontainers handles Docker directly | |
| # Skipping Buildx prevents unnecessary image pulls during initialization | |
| - name: Pre-pull Docker images for caching | |
| if: matrix.db_type != 'tidb' | |
| run: | | |
| docker pull ${{ matrix.docker_image }} || true | |
| - name: Pre-pull TiDB images for caching | |
| if: matrix.db_type == 'tidb' | |
| run: | | |
| docker pull pingcap/tidb:v${{ matrix.db_version }} || true | |
| docker pull pingcap/pd:v${{ matrix.db_version }} || true | |
| docker pull pingcap/tikv:v${{ matrix.db_version }} || true | |
| - name: Run testcontainers tests | |
| env: | |
| GOFLAGS: -mod=vendor | |
| TF_ACC: 1 | |
| GOTOOLCHAIN: auto | |
| run: | | |
| export PATH="${{ github.workspace }}/bin:$PATH" | |
| if [ "${{ matrix.db_type }}" == "tidb" ]; then | |
| export TIDB_VERSION=${{ matrix.db_version }} | |
| if [ -z "$TIDB_VERSION" ]; then | |
| echo "ERROR: TIDB_VERSION is not set for TiDB test" | |
| exit 1 | |
| fi | |
| go test -tags=testcontainers -v ./mysql/... -run WithTestcontainers -timeout=30m | |
| else | |
| export DOCKER_IMAGE=${{ matrix.docker_image }} | |
| if [ -z "$DOCKER_IMAGE" ]; then | |
| echo "ERROR: DOCKER_IMAGE is not set for ${{ matrix.db_type }} test" | |
| exit 1 | |
| fi | |
| echo "Using Docker image: $DOCKER_IMAGE" | |
| go test -tags=testcontainers -v ./mysql/... -run WithTestcontainers -timeout=30m | |
| fi | |
| release: | |
| name: Release | |
| needs: [tests] | |
| # Can't use non-semvar for the testing tag | |
| # https://github.com/orgs/goreleaser/discussions/3708 | |
| if: ( startsWith( github.ref, 'refs/tags/v' ) || | |
| startsWith(github.ref, 'refs/tags/v0.0.0-rc') ) | |
| runs-on: ubuntu-22.04 | |
| permissions: | |
| contents: write # Required for creating releases | |
| steps: | |
| - name: Checkout Git repo | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Full history needed for changelog | |
| - name: Set up Go | |
| uses: actions/setup-go@v4 | |
| with: | |
| go-version-file: go.mod | |
| - name: Import GPG Subkey | |
| env: | |
| GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} | |
| GPG_FINGERPRINT: ${{ secrets.GPG_FINGERPRINT }} | |
| GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} | |
| run: | | |
| # Create GPG directory | |
| mkdir -p ~/.gnupg | |
| chmod 700 ~/.gnupg | |
| # Configure GPG for non-interactive use with passphrase | |
| echo "use-agent" >> ~/.gnupg/gpg.conf | |
| echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf | |
| echo "allow-loopback-pinentry" >> ~/.gnupg/gpg.conf | |
| # Start gpg-agent with loopback pinentry (ignore error if already running) | |
| gpg-agent --daemon --allow-loopback-pinentry 2>&1 || true | |
| # Import the subkey | |
| # Write key to temp file (key data is okay, but passphrase never touches disk) | |
| KEY_FILE=$(mktemp) | |
| echo "$GPG_PRIVATE_KEY" > "$KEY_FILE" | |
| # Get keygrip from the key without importing (dry-run with import-show) | |
| IMPORT_OUTPUT=$(gpg --batch --with-colons --import-options import-show --dry-run --import "$KEY_FILE" 2>&1 || true) | |
| KEYGRIP=$(echo "$IMPORT_OUTPUT" | grep -E "^grp:" | cut -d: -f10 | head -1) | |
| # If we found a keygrip, preset the passphrase in gpg-agent (passphrase never touches disk) | |
| # gpg-preset-passphrase communicates directly with gpg-agent via socket | |
| if [ -n "$KEYGRIP" ]; then | |
| echo "$GPG_PASSPHRASE" | gpg-preset-passphrase --preset "$KEYGRIP" 2>&1 || true | |
| fi | |
| # Now import the key (passphrase is cached in gpg-agent if keygrip was found) | |
| # If keygrip wasn't found, use passphrase-fd (passphrase from env var, not disk) | |
| if [ -n "$KEYGRIP" ]; then | |
| gpg --batch --yes --import "$KEY_FILE" | |
| else | |
| # Fallback: passphrase comes from environment variable via stdin, never written to disk | |
| echo "$GPG_PASSPHRASE" | gpg --batch --yes --pinentry-mode loopback --passphrase-fd 0 --import "$KEY_FILE" | |
| fi | |
| # Clean up temp file (only contains key data, not passphrase) | |
| rm -f "$KEY_FILE" | |
| # Trust the key (required for signing) | |
| # Use ultimate trust (6) for the subkey | |
| echo "$GPG_FINGERPRINT:6:" | gpg --import-ownertrust | |
| # Verify key is available and can sign | |
| gpg --list-secret-keys --keyid-format LONG | |
| # Test signing capability | |
| # Passphrase should be cached in gpg-agent from preset-passphrase above | |
| # If not cached, this will fail and we'll know import didn't work | |
| echo "test" | gpg --batch --pinentry-mode loopback --sign --armor > /dev/null 2>&1 && echo "✓ GPG signing test successful" || echo "⚠ GPG signing test failed - passphrase may not be cached" | |
| - name: Run GoReleaser | |
| uses: goreleaser/goreleaser-action@v6 | |
| with: | |
| distribution: goreleaser | |
| version: '~> v2' | |
| # Run goreleaser and ignore non-committed files (downloaded artifacts) | |
| args: release --clean --skip=validate | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GPG_FINGERPRINT: ${{ secrets.GPG_FINGERPRINT }} | |
| GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} | |
| GPG_TTY: $(tty) | |
| # terraform-provider-release: | |
| # needs: [release] | |
| # name: 'Terraform Provider Release' | |
| # uses: hashicorp/ghaction-terraform-provider-release/.github/workflows/community.yml@v5 | |
| # secrets: | |
| # gpg-private-key: '${{ secrets.GPG_PRIVATE_KEY }}' | |
| # with: | |
| # setup-go-version-file: 'go.mod' |