Skip to content

Generate CDKTF Go Bindings #105

Generate CDKTF Go Bindings

Generate CDKTF Go Bindings #105

# .github/workflows/generate-bindings.yml
# This workflow automates the generation and publication of CDKTF Go provider bindings
# It consists of two jobs
# 1) Find the missing bindings version for the available provider versions
# 2) Create a matrix on all missing versions and create and publish the bindings for them
# It's designed to be run manually and on schedule
name: Generate CDKTF Go Bindings
on:
workflow_dispatch: {} # Allows you to run this workflow manually from the Actions tab or via API
schedule:
- cron: '0 3 * * *' # Every day at 3 AM
env:
# --- Configuration ---
# The namespace of the provider
NAMESPACE: "stackitcloud"
# The name of the provider
PROVIDER: "stackit"
# The Go version to use for the build.
GO_VERSION: '1.24'
# The Node.js version to use for the CDKTF CLI.
NODE_VERSION: '22'
# The Terraform version to use for the CDKTF CLI.
TERRAFORM_VERSION: '1.12'
# The Git repository host
GIT_HOST: 'github.com'
# The Git user to commit changes
GIT_USER: 'github-actions[bot]'
# The Git email to commit changes
GIT_EMAIL: 'github-actions[bot]@github.com'
jobs:
find-missing-versions:
name: Find Missing Versions
runs-on: ubuntu-latest
outputs:
versions: ${{ steps.find-missing-versions.outputs.versions }}
steps:
# 1. Checkout Repository
# Checks out your repository under $GITHUB_WORKSPACE, so your job can access it.
- name: 📤 Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for fetch-tags to work
fetch-tags: true # Required for git tag to work
# 2. Find Missing Versions
# Checks out your repository under $GITHUB_WORKSPACE, so your job can access it.
- name: 🔎 Find Missing Versions
id: find-missing-versions
run: |
cd $GITHUB_WORKSPACE
# Download available versions of provider
curl -s 'https://registry.terraform.io/v1/providers/stackitcloud/stackit' | jq -r '.versions.[]' | sort -V > provider-versions.txt
# Skip first two releases, as cdktf cannot build them
echo -e "0.1.0\n0.1.1" > tagged-versions.txt
# Get available versions
git tag | grep -Po "stackit/v\K.+" | sort -V >> tagged-versions.txt
# Calculate missing versions
echo "versions=$(grep -v -x -f tagged-versions.txt provider-versions.txt | jq --raw-input --raw-output --compact-output --slurp 'split("\n") | map(select(. != ""))')" >> $GITHUB_OUTPUT
generate-bindings:
name: Generate and Publish Bindings
needs: [find-missing-versions]
runs-on: ubuntu-latest
permissions:
# Required to commit changes and create releases.
contents: write
if: needs.find-missing-versions.outputs.versions != '[]'
strategy:
max-parallel: 1 # Create versions sequentially to avoid merge conflicts
matrix:
version: ${{ fromJSON(needs.find-missing-versions.outputs.versions) }}
steps:
# 1. Checkout Repository
# Checks out your repository under $GITHUB_WORKSPACE, so your job can access it.
- name: 📤 Checkout Repository
uses: actions/checkout@v4
with:
ref: main # Force most-recent branch version to include previous job executions
# 2. Setup Go Environment
- name: 🛠 Setup Go
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
cache-dependency-path: |
stackit/go.sum
# 3. Setup Node.js Environment (for CDKTF CLI)
- name: 🛠 Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
# 4. Setup Terraform (for CDKTF CLI)
- name: 🛠 Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TERRAFORM_VERSION }}
# 5. Install CDKTF CLI
- name: 🛠 Install CDKTF CLI
run: npm install --global cdktf-cli
# 6. Initialize CDKTF Project and Generate Bindings
# This step creates a clean CDKTF project to generate the provider bindings from.
# The "<<< 'n'" here string passes "no" to the interactive enable crash reporting question
- name: 🏗️ Initialize CDKTF Project and Generate Bindings
run: |
echo "Create temporary directory..."
mkdir temp-init
cd temp-init
echo "Initialize project with provider, which automatically generates bindings..."
cdktf init --template="go" --providers="${{ env.NAMESPACE }}/${{ env.PROVIDER }}@${{ matrix.version }}" --project-name "cdktf-provider-stackit-go" --project-description "cdktf-provider-stackit-go" --providers-force-local --local <<< 'n'
# 7. Finalize Go Module
# Sets the correct module path and tidies dependencies.
- name: 🧹 Tidy Go Module
run: |
cd temp-init
echo "Set the module path to match our repository url..."
go mod edit -module ${{ env.GIT_HOST }}/${{ github.repository }}/${{ env.PROVIDER }}
echo "Replace all temporary module import paths with the public git module..."
find ./generated -type f -name '*.go' -exec sed -i 's|cdk.tf/go/stack/generated/${{ env.NAMESPACE }}/${{ env.PROVIDER }}|${{ env.GIT_HOST }}/${{ github.repository }}/${{ env.PROVIDER }}|g' {} \;
echo "Move the go.mod to the correct folder..."
mv go.mod ./generated/${{ env.NAMESPACE }}/${{ env.PROVIDER }}/go.mod
cd ./generated/${{ env.NAMESPACE }}/${{ env.PROVIDER }}
echo "Tidy on the generated module with updated import paths..."
go mod tidy
echo "Create version file..."
echo "${{ matrix.version }}" > version
# 8. Restructure Files
# This step transforms the generated output into a clean Go module at the repository root.
- name: 🚚 Move Generated Code
run: |
echo "Remove old provider..."
rm -rf ${{ env.PROVIDER }}
echo "Moving generated provider code to root..."
mv temp-init/generated/${{ env.NAMESPACE }}/${{ env.PROVIDER }} .
echo "Cleaning up temporary directories..."
rm -rf temp-init
# 9. Commit and Tag
# Commits the newly generated files and tags the release.
- name: 🚀 Commit, Tag, and Push Changes
run: |
git config --global user.name '${{ env.GIT_USER }}'
git config --global user.email '${{ env.GIT_EMAIL }}'
git add .
if git diff --staged --quiet; then
echo "No changes to commit. The bindings are already up-to-date."
# Exit the script with failing state to avoid creating a release
exit -1
fi
COMMIT_MSG="feat(provider): Generate bindings for v${{ matrix.version }}"
echo "Committing new version..."
git commit -m "$COMMIT_MSG"
TAG="${{ env.PROVIDER }}/v${{ matrix.version }}"
echo "Tagging new version as $TAG"
git tag $TAG
echo "Pushing commit and tag to origin..."
git push origin HEAD
git push origin --tags
# 10. Create Release
# Creates a formal release on GitHub associated with the new tag.
- name: 📦 Create Release
uses: softprops/action-gh-release@v2
# This condition ensures that the release is only created if there were changes to commit.
if: success()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
name: v${{ matrix.version }}
tag_name: ${{ env.PROVIDER }}/v${{ matrix.version }}
body: |
Automated release of Go bindings for Terraform provider ${{ env.NAMESPACE }}/${{ env.PROVIDER }}@${{ matrix.version }}.
draft: false
prerelease: false