Publish Hex Release #38
This file contains 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: "Publish Hex Release" | |
on: | |
workflow_dispatch: | |
inputs: | |
package: | |
description: "Package" | |
type: choice | |
options: | |
- "aws_xray" | |
- "broadway" | |
- "cowboy" | |
- "dataloader" | |
- "ecto" | |
- "elli" | |
- "finch" | |
- "grpcbox" | |
- "http_instrumentation" | |
- "httpoison" | |
- "nebulex" | |
- "oban" | |
- "opentelemetry_telemetry" | |
- "phoenix" | |
- "process_propagator" | |
- "redix" | |
- "req" | |
- "tesla" | |
- "xandra" | |
required: true | |
action: | |
description: "Publish release" | |
required: true | |
type: choice | |
options: | |
- prep | |
- publish | |
jobs: | |
config: | |
runs-on: ubuntu-latest | |
outputs: | |
authorized_users: ${{ steps.set-config.outputs.authorized_users }} | |
build_tool: ${{ steps.set-config.outputs.build_tool }} | |
language: ${{ steps.set-config.outputs.language }} | |
name: ${{ steps.set-config.outputs.name }} | |
package_name: ${{ steps.set-config.outputs.package_name }} | |
tag_prefix: ${{ steps.set-config.outputs.tag_prefix}} | |
working_directory: ${{ steps.set-config.outputs.working_directory }} | |
steps: | |
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | |
- name: Read file | |
id: set-config | |
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 | |
env: | |
package: ${{ inputs.package }} | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
const fs = require('fs'); | |
const steps = ${{ toJson(steps) }}; | |
const configFile = JSON.parse(fs.readFileSync('.github/hex-packages.json', 'UTF8')) | |
const packageConfig = configFile[process.env.package] | |
const workingDir = packageConfig['workingDirectory'] | |
switch(workingDir) { | |
case undefined: | |
case '': | |
core.setOutput('working_directory', './') | |
break; | |
default: | |
core.setOutput('working_directory', workingDir) | |
} | |
core.setOutput('name', packageConfig.name) | |
core.setOutput('package_name', packageConfig.packageName) | |
core.setOutput('tag_prefix', packageConfig.tagPrefix) | |
core.setOutput('build_tool', packageConfig.buildTool) | |
core.setOutput('language', packageConfig.language) | |
core.setOutput('authorized_users', packageConfig.authorizedUsers) | |
authorized_publisher: | |
needs: config | |
runs-on: ubuntu-latest | |
steps: | |
- run: ${{ contains(fromJson(needs.config.outputs.authorized_users), github.actor) }} | |
publish: | |
needs: [authorized_publisher, config] | |
runs-on: ubuntu-latest | |
permissions: | |
# write permission is required to create a github release | |
contents: write | |
pull-requests: write | |
steps: | |
- name: "Fetch Github Draft Release" | |
id: fetch-release | |
run: | | |
release="$(gh api repos/${{ github.repository }}/releases --jq '.[] | select(.draft == true) | select(.tag_name | test("^${{ needs.config.outputs.tag_prefix }}"))')" | |
echo "gh_release=$release" >> $GITHUB_OUTPUT | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name: Checkout | |
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | |
- run: npm install semver | |
- name: "Update Files" | |
id: update-files | |
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
const fs = require('fs'); | |
const semver = require('semver'); | |
const needs = ${{ toJson(needs) }}; | |
const steps = ${{ toJson(steps) }}; | |
const ghRelease = JSON.parse(steps["fetch-release"]["outputs"]["gh_release"]) | |
const semverRegex = /v(?<tagvsn>\d+\.\d+\.\d+)$/; | |
let match = ghRelease.tag_name.match(semverRegex); | |
let version = match.groups.tagvsn; | |
core.exportVariable('package_version', version); | |
core.exportVariable('gh_release_tag_name', ghRelease.tag_name) | |
core.info(`Draft release tag to be created: ${version}`) | |
var srcFilePath = ""; | |
var srcVersionRegex = ""; | |
var vsnLineTemplate = ""; | |
core.debug(`Language: ${needs.config.outputs.language}`) | |
switch(needs.config.outputs.language) { | |
case 'elixir': | |
srcFilePath = `${needs.config.outputs.working_directory}/mix.exs`; | |
core.debug(`Source file path: ${srcFilePath}`) | |
srcVersionRegex = /@version\s+"[^"]+"/; | |
core.debug(`Source version regex: ${srcVersionRegex}`) | |
vsnLineTemplate = `@version "${version}"`; | |
core.debug(`Version line template: ${vsnLineTemplate}`) | |
core.setOutput('srcFilePath', srcFilePath); | |
break; | |
case 'elixir-erlang': | |
case 'erlang': | |
srcFilePath = `${needs.config.outputs.working_directory}/src/${needs.config.outputs.package_name}.app.src`; | |
core.debug(`Source file path: ${srcFilePath}`) | |
srcVersionRegex = /{vsn,\s+"[^"]+"},/; | |
core.debug(`Source version regex: ${srcVersionRegex}`) | |
vsnLineTemplate = `{vsn, "${version}"},`; | |
core.debug(`Version line template: ${vsnLineTemplate}`) | |
core.setOutput('srcFilePath', srcFilePath); | |
break; | |
default: | |
core.setFailed('Language not recognized'); | |
} | |
core.info(`srcFilePath: ${srcFilePath}`) | |
let srcFile = fs.readFileSync(srcFilePath, 'UTF8') | |
var srcVersion = srcFile.match(srcVersionRegex)[0].split('"')[1] | |
core.exportVariable('src_file_version', srcVersion) | |
core.info(`Source file version: ${srcVersion}`) | |
core.exportVariable('releasePrepped', true) | |
core.setOutput('srcFileUpdated', false) | |
if (!semver.eq(version, srcVersion)) { | |
core.exportVariable('releasePrepped', false) | |
core.exportVariable('published', false) | |
if (semver.lt(version, srcVersion)) { | |
core.setFailed(`Proposed package version does not increment the current version`) | |
} else { | |
core.setOutput('prRequired') | |
core.notice('Release not ready. Creating PR.') | |
let updatedSrcFile = srcFile.replace(srcVersionRegex, vsnLineTemplate); | |
fs.writeFileSync(srcFilePath, updatedSrcFile); | |
core.setOutput('srcFileUpdated', true) | |
} | |
} | |
- uses: erlef/setup-beam@b9c58b0450cd832ccdb3c17cc156a47065d2114f # v1.18.1 | |
with: | |
version-type: strict | |
otp-version: "25.3.2.5" | |
elixir-version: "1.14.5" | |
rebar3-version: "3.22.1" | |
- name: "Mix Hex Publish Dry-run" | |
if: ${{ needs.config.outputs.build_tool == 'mix' }} | |
working-directory: ${{ needs.config.outputs.working_directory }} | |
env: | |
HEX_API_KEY: ${{ secrets.OTEL_HEX_KEY }} | |
run: | | |
mix deps.get | |
mix hex.publish --dry-run --yes | |
- name: "Rebar3 Hex Publish Dry-run" | |
if: ${{ needs.config.outputs.build_tool == 'rebar3' }} | |
working-directory: ${{ needs.config.outputs.working_directory }} | |
env: | |
HEX_API_KEY: ${{ secrets.OTEL_HEX_KEY }} | |
run: | | |
rebar3 upgrade | |
rebar3 hex publish --dry-run --yes | |
- name: "Open a Version Update PR" | |
if: ${{ env.releasePrepped == 'false' }} | |
id: version-update-pr | |
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 | |
with: | |
add-paths: | | |
${{ steps.update-files.outputs.srcFilePath }} | |
base: main | |
branch: "${{ needs.config.outputs.tag_prefix }}${{ env.package_version }}-release" | |
commit-message: "Prep release v${{ env.package_version }}" | |
body: | | |
Prepare hex release v${{ env.package_version }} | |
labels: | | |
automated-pr | |
release | |
skip-changelog | |
title: "${{ needs.config.outputs.name }} v${{ env.package_version }}" | |
token: ${{ secrets.GITHUB_TOKEN }} | |
- name: "Publish Github Release" | |
if: ${{ env.releasePrepped == 'true' && inputs.action == 'publish' }} | |
id: publish-gh-release | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
gh release edit ${{ env.gh_release_tag_name }} --draft=false --latest | |
- name: "Mix Publish to Hex" | |
id: mix-hex-publish | |
if: ${{ env.releasePrepped == 'true' && inputs.action == 'publish' && needs.config.outputs.build_tool == 'mix' }} | |
working-directory: ${{ needs.config.outputs.working_directory }} | |
env: | |
HEX_API_KEY: ${{ secrets.OTEL_HEX_KEY }} | |
run: | | |
mix hex.publish --yes | |
echo "published=true" >> $GITHUB_ENV | |
- name: "Rebar3 Publish to Hex" | |
id: rebar3-hex-publish | |
if: ${{ env.releasePrepped == 'true' && inputs.action == 'publish' && needs.config.outputs.build_tool == 'rebar3' }} | |
working-directory: ${{ needs.config.outputs.working_directory }} | |
env: | |
HEX_API_KEY: ${{ secrets.OTEL_HEX_KEY }} | |
run: | | |
rebar3 upgrade | |
rebar3 hex publish --yes | |
echo "published=true" >> $GITHUB_ENV |