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 # TEMPORARY: triage for the npm E401 on publish. Prints lengths and # status codes only, never a token value. - name: Triage the publish token env: TOKEN: ${{ secrets.GITEA_TOKEN }} run: | echo "token length: ${#TOKEN}" echo -n "GET /api/v1/user -> " curl -s -o /dev/null -w '%{http_code}\n' \ -H "Authorization: token $TOKEN" "https://${GITEA_HOST}/api/v1/user" echo -n "GET /api/v1/packages/owner -> " curl -s -o /dev/null -w '%{http_code}\n' \ -H "Authorization: token $TOKEN" "https://${GITEA_HOST}/api/v1/packages/${GITEA_OWNER}?limit=1" echo -n "npm registry GET (basic) -> " curl -s -o /dev/null -w '%{http_code}\n' \ -u "${GITEA_OWNER}:$TOKEN" \ "https://${GITEA_HOST}/api/packages/${GITEA_OWNER}/npm/@maxvojtkov%2Fpulumi-dokploy" # A write with a deliberately empty body: 401 means the credentials # were refused, anything else means they were accepted and only the # payload was rejected. That is what separates "wrong token" from # "wrong auth scheme". echo -n "npm PUT (bearer, as npm) -> " curl -s -o /dev/null -w '%{http_code}\n' -X PUT \ -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \ -d '{}' "https://${GITEA_HOST}/api/packages/${GITEA_OWNER}/npm/@maxvojtkov%2Fpulumi-dokploy" echo -n "npm PUT (basic) -> " curl -s -o /dev/null -w '%{http_code}\n' -X PUT \ -u "${GITEA_OWNER}:$TOKEN" -H 'Content-Type: application/json' \ -d '{}' "https://${GITEA_HOST}/api/packages/${GITEA_OWNER}/npm/@maxvojtkov%2Fpulumi-dokploy" - 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: | # `_authToken` makes npm send `Authorization: Bearer`, which this # Gitea refuses for the token Actions injects -- the publish failed # with E401 while the very same token authenticated fine over Basic. # `_auth` is base64 user:token, i.e. Basic. cat > .npmrc <@/` 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}"