Add GitHub Actions workflow to publish Gleam package#4
Conversation
Introduces a workflow for publishing the Gleam package to Hex when a tag matching v* is pushed or a PR is merged to main. The workflow includes steps for environment setup, dependency installation, build, test, version verification, Hex API key validation, publishing, and GitHub release creation.
There was a problem hiding this comment.
Pull Request Overview
This PR introduces a GitHub Actions workflow to automate publishing the Gleam package "thrifty" to Hex.pm. The workflow is designed to trigger on both tag pushes (v*) and merged PRs to main, with steps for building, testing, version verification, and publishing.
Key Changes:
- Adds automated Hex.pm publishing with tag-based and PR-based triggers
- Implements version verification between git tags and gleam.toml
- Includes HEX API key validation and duplicate version detection
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| HEX_API_KEY: ${{ secrets.HEX_API_KEY }} | ||
| run: | | ||
| set -euo pipefail | ||
| echo "Publishing with gleam publish --yes" |
There was a problem hiding this comment.
The piped input "I am not using semantic versioning" appears to be handling an interactive prompt from gleam publish. This should be documented in a comment explaining why this input is needed, as it's not immediately clear what prompt this is responding to or if this is the correct response.
| echo "Publishing with gleam publish --yes" | |
| echo "Publishing with gleam publish --yes" | |
| # gleam publish prompts for confirmation if the version is not semver; this input answers the prompt. | |
| # See: https://github.com/gleam-lang/gleam/issues/2542 |
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: gleam-hex-package | ||
| path: _build/default/lib/thrifty/hex/thrifty-*.tar || true |
There was a problem hiding this comment.
The artifact path appears to be hardcoded with the package name "thrifty". If this workflow is intended to be reusable or the package name changes, this path should use the dynamically extracted package name from gleam.toml (similar to line 134) or use a wildcard pattern like _build/default/lib/*/hex/*.tar.
| path: _build/default/lib/thrifty/hex/thrifty-*.tar || true | |
| path: _build/default/lib/*/hex/*.tar |
| echo "Tag ${TAG} already exists, skipping" | ||
| exit 0 |
There was a problem hiding this comment.
When a tag already exists (line 92), the step exits with code 0 but the workflow continues. This means the workflow will attempt to verify and publish using a version that may not match the current state. The job-level if condition (line 29-30) checks for tag refs, but after exiting at line 93, GITHUB_REF still won't contain a tag reference. Consider restructuring the logic to either fail the workflow or properly set the tag reference for subsequent steps.
| echo "Tag ${TAG} already exists, skipping" | |
| exit 0 | |
| echo "Tag ${TAG} already exists, aborting workflow." | |
| exit 1 |
| fi | ||
|
|
||
| - name: Publish to Hex | ||
| if: startsWith(github.ref, 'refs/tags/') || (github.event_name == 'pull_request' && github.event.pull_request.merged == true) |
There was a problem hiding this comment.
The conditional logic here is checking startsWith(github.ref, 'refs/tags/'), but when triggered by a merged PR, the "Create tag from gleam.toml" step (line 83-99) may have skipped tag creation if the tag already existed. This means the publish step might execute even when no tag is present in the current context. The condition should be more robust to ensure a valid version context exists before publishing.
| - name: Determine version from tag | ||
| id: ver | ||
| run: | | ||
| TAG=${GITHUB_REF#refs/tags/} | ||
| VERSION=${TAG#v} | ||
| echo "Determined version ${VERSION} from tag ${TAG}" | ||
| echo "version=${VERSION}" >> $GITHUB_OUTPUT |
There was a problem hiding this comment.
The "Determine version from tag" step will fail when the workflow is triggered by a merged PR, since GITHUB_REF won't contain a tag reference at this point (the tag is created later in line 83-99). This step should be conditional on tag push events only, or the logic needs to be restructured to handle both trigger types.
| - name: Verify tag matches `gleam.toml` | ||
| run: | | ||
| VERSION="${{ steps.ver.outputs.version }}" | ||
| FILE_VER=$(grep '^version' gleam.toml | sed -E 's/.*= *"([^"]+)".*/\1/') || true | ||
| echo "gleam.toml version: ${FILE_VER}" | ||
| if [ -n "${FILE_VER}" ] && [ "${FILE_VER}" != "${VERSION}" ]; then | ||
| echo "Tag version (${VERSION}) does not match gleam.toml (${FILE_VER}). Aborting publish." | ||
| exit 1 | ||
| fi |
There was a problem hiding this comment.
This verification step references steps.ver.outputs.version which is only set by the "Determine version from tag" step (line 75-81). When triggered by a merged PR, the version won't be extracted at that point since the tag doesn't exist yet. This step needs to either: (1) be conditional on tag push events only, or (2) extract the version from gleam.toml when triggered by PR merge.
| run: | | ||
| set -euo pipefail | ||
| PACKAGE=$(grep '^name' gleam.toml | sed -E 's/.*= *"([^"]+)".*/\1/') | ||
| VERSION="${{ steps.ver.outputs.version }}" |
There was a problem hiding this comment.
This step references steps.ver.outputs.version which may not be set when the workflow is triggered by a merged PR. The version extraction logic needs to handle both trigger types (tag push and merged PR) consistently.
| if curl -s "https://hex.pm/api/packages/${PACKAGE}" | jq -e ".releases[] | select(.version==\"${VERSION}\")" > /dev/null; then | ||
| echo "Version ${VERSION} already exists on Hex. Skipping publish." | ||
| exit 0 |
There was a problem hiding this comment.
The exit 0 here doesn't prevent subsequent steps from running. If the version already exists on Hex, the workflow will continue to the "Publish to Hex" step which will likely fail. Consider using exit 1 with an appropriate error message, or set an output variable to conditionally skip the publish step.
Introduces a workflow for publishing the Gleam package to Hex when a tag matching v* is pushed or a PR is merged to main. The workflow includes steps for environment setup, dependency installation, build, test, version verification, Hex API key validation, publishing, and GitHub release creation.