Files
pulumi-dokploy/.gitea/workflows/release.yml
T
max-voitcov 381c928342
build / build (push) Successful in 14m12s
Give the SDK job the pulumi CLI it has always needed
The v0.2.0 plugin binaries published, then the SDK job died in tfgen:

    panic: fatal: error An assertion has failed: bulk converting examples
    failed. convertViaPulumiCLI: pulumi executable not in PATH

tfgen converts the upstream provider's documentation examples into each
language by shelling out to `pulumi convert`, and asserts rather than degrades
when the binary is missing. The build workflow installs the CLI; this job never
did. It went unnoticed through v0.1.0 because tfgen had no docs to convert
until UpstreamRepoPath pointed it at the upstream checkout.

So half a release is published and the other half is not, and re-pushing the
tag would rerun a 45 minute build against artifacts that are already uploaded.
Let a dispatch republish just the SDKs instead: it takes the tag to publish,
skips the plugin job, and checks the tree out at that tag while the workflow
file itself comes from the branch it was dispatched on.
2026-08-26 02:52:02 +03:00

197 lines
7.5 KiB
YAML

name: release
on:
push:
tags: ["v*.*.*"]
# A release that dies halfway -- the runner OOMs, the host reboots, a job is
# missing a tool -- leaves the tag pushed and only part of the release
# published, and re-pushing a tag to retry it is both awkward and
# destructive. Dispatch republishes the SDKs for a tag that already has its
# plugin binaries, which is the half that fails: the plugin job is a 45
# minute build that either produced its artifacts or did not.
workflow_dispatch:
inputs:
tag:
description: Tag to publish the SDKs for, e.g. v0.2.0
required: true
env:
GO_VERSION: "1.25.x"
NODE_VERSION: "20.x"
PYTHON_VERSION: "3.11"
DOTNET_VERSION: "8.0.x"
UPSTREAM_REPO: usr_unknown/terraform-provider-dokploy
UPSTREAM_DIR: dokploy-teraform
# Everything below authenticates with the token Gitea injects into every
# run, so releasing needs no configured secrets at all.
GITEA_HOST: gitea.coolify.vojtkov.dev
GITEA_OWNER: usr_unknown
jobs:
# The plugin binaries. Pulumi resolves them from this release via the
# PluginDownloadURL baked into the schema, so this has to land before anyone
# installs an SDK.
plugin:
# Only on a tag push. A dispatch is for republishing SDKs against a tag
# whose binaries are already uploaded, and goreleaser would collide with
# them. To rebuild the binaries themselves, delete the release and
# re-push the tag.
if: github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
path: pulumi-dokploy
fetch-depth: 0
- uses: actions/checkout@v4
with:
repository: ${{ env.UPSTREAM_REPO }}
path: ${{ env.UPSTREAM_DIR }}
token: ${{ secrets.GITEA_TOKEN }}
# checkout's default-branch lookup returns "not found" on this Gitea.
ref: main
- uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: false
# A bridged Pulumi provider links the whole Terraform provider plus the
# Pulumi SDK into one ~100MB binary, and compiling that is memory-hungry.
# goreleaser defaults its parallelism to the CPU count, so several of
# those compiles overlap and the runner OOMs -- the v0.2.0 release died
# after 31 minutes with `compile: signal: killed` on darwin_amd64.
#
# Build one target at a time. It is slower in wall-clock but it is the
# difference between a release that finishes and one that does not.
# GOGC trades some CPU for a lower peak heap in the compiler itself.
- uses: goreleaser/goreleaser-action@v6
with:
version: latest
args: release --clean --parallelism 1
workdir: pulumi-dokploy
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
GOGC: "50"
sdks:
needs: plugin
# `always()` so a dispatch, where plugin is skipped rather than run, still
# gets here -- but not past a plugin job that actually failed.
if: always() && needs.plugin.result != 'failure' && needs.plugin.result != 'cancelled'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
path: pulumi-dokploy
# The workflow file comes from the dispatched branch; the tree to
# publish comes from the tag. On a push the two are the same thing.
ref: ${{ inputs.tag || github.ref }}
# Needed for the tag lookup below.
fetch-depth: 0
- uses: actions/checkout@v4
with:
repository: ${{ env.UPSTREAM_REPO }}
path: ${{ env.UPSTREAM_DIR }}
token: ${{ secrets.GITEA_TOKEN }}
# checkout's default-branch lookup returns "not found" on this Gitea.
ref: main
- uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: false
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
# tfgen converts the upstream provider's documentation examples into
# each language by shelling out to `pulumi convert`, and asserts rather
# than degrades when the binary is absent: "pulumi executable not in
# PATH". It only started mattering once UpstreamRepoPath gave tfgen
# docs to find, which is why v0.1.0 published without this.
- uses: pulumi/actions@v6
# On a tag push the ref name is the tag; on a dispatch it is the branch,
# so ask git what tag this commit carries. --exact-match keeps a dispatch
# from quietly publishing an untagged commit under the previous version.
- name: Derive version from tag
working-directory: pulumi-dokploy
run: |
TAG="$(git describe --tags --exact-match)"
echo "VERSION=${TAG#v}" >> "$GITHUB_ENV"
- name: Build SDKs
working-directory: pulumi-dokploy
run: make build_sdks VERSION=${{ env.VERSION }}
- name: Publish to the Gitea npm registry
working-directory: pulumi-dokploy/sdk/nodejs/bin
env:
TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
cat > .npmrc <<EOF
@maxvojtkov:registry=https://${GITEA_HOST}/api/packages/${GITEA_OWNER}/npm/
//${GITEA_HOST}/api/packages/${GITEA_OWNER}/npm/:_authToken=${TOKEN}
EOF
npm publish
- name: Publish to the Gitea PyPI registry
working-directory: pulumi-dokploy/sdk/python
env:
TWINE_USERNAME: ${{ env.GITEA_OWNER }}
TWINE_PASSWORD: ${{ secrets.GITEA_TOKEN }}
run: |
python -m pip install --upgrade build twine
python -m build
python -m twine upload \
--repository-url "https://${GITEA_HOST}/api/packages/${GITEA_OWNER}/pypi" \
dist/*
- name: Publish to the Gitea NuGet registry
working-directory: pulumi-dokploy/sdk/dotnet
env:
TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
dotnet pack --configuration Release --output ./nupkg
dotnet nuget push ./nupkg/*.nupkg \
--source "https://${GITEA_HOST}/api/packages/${GITEA_OWNER}/nuget/index.json" \
--api-key "$TOKEN" --skip-duplicate
# The Go SDK's module path stays github.com/maxvojtkov/..., which no
# amount of Gitea hosting changes. Uploading it to Gitea's Go registry is
# what makes that path resolvable anyway: consumers point GOPROXY here.
#
# A module zip must have every entry prefixed `<module>@<version>/` and
# must contain no directory entries at all -- hence `zip -D`, without
# which `go get` fails with "has unexpected file".
- name: Publish the Go SDK to the Gitea Go registry
working-directory: pulumi-dokploy
env:
TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -euo pipefail
MODULE=github.com/maxvojtkov/pulumi-dokploy/sdk
STAGE="$(mktemp -d)"
DEST="$STAGE/$MODULE@v${VERSION}"
mkdir -p "$DEST"
cp sdk/go.mod sdk/go.sum "$DEST/"
cp -R sdk/go "$DEST/"
(cd "$STAGE" && zip -qrD "$STAGE/sdk.zip" . -x 'sdk.zip')
curl -fsSL -X PUT \
--user "${GITEA_OWNER}:${TOKEN}" \
--upload-file "$STAGE/sdk.zip" \
"https://${GITEA_HOST}/api/packages/${GITEA_OWNER}/go/upload"
echo "Published $MODULE@v${VERSION}"