Hex publishing workflow (#250)

* Add Hex publishing manual workflow
This commit is contained in:
Bryan Naegele 2024-02-04 17:18:14 -07:00 committed by GitHub
parent d202470ebc
commit bf6adb78e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 451 additions and 16 deletions

155
.github/hex-packages.json vendored Normal file
View File

@ -0,0 +1,155 @@
{
"aws_xray": {
"workingDirectory": "utilities/opentelemetry_aws_xray",
"name": "AWS Xray Utility",
"packageName": "opentelemetry_aws_xray",
"tagPrefix": "opentelemetry-aws-xray-v",
"buildTool": "rebar3",
"language": "erlang",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"cowboy": {
"workingDirectory": "instrumentation/opentelemetry_cowboy",
"name": "Cowboy Instrumentation",
"packageName": "opentelemetry_cowboy",
"tagPrefix": "opentelemetry-cowboy-v",
"buildTool": "rebar3",
"language": "erlang",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"dataloader": {
"workingDirectory": "instrumentation/opentelemetry_dataloader",
"name": "Dataloader Instrumentation",
"packageName": "opentelemetry_dataloader",
"tagPrefix": "opentelemetry-dataloader-v",
"buildTool": "mix",
"language": "elixir",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"ecto": {
"workingDirectory": "instrumentation/opentelemetry_ecto",
"name": "Ecto Instrumentation",
"packageName": "opentelemetry_ecto",
"tagPrefix": "opentelemetry-ecto-v",
"buildTool": "mix",
"language": "elixir",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"elli": {
"workingDirectory": "instrumentation/opentelemetry_elli",
"name": "Elli Instrumentation",
"packageName": "opentelemetry_elli",
"tagPrefix": "opentelemetry-elli-v",
"buildTool": "rebar3",
"language": "erlang",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"finch": {
"workingDirectory": "instrumentation/opentelemetry_finch",
"name": "Finch Instrumentation",
"packageName": "opentelemetry_finch",
"tagPrefix": "opentelemetry-finch-v",
"buildTool": "mix",
"language": "elixir",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"grpcbox": {
"workingDirectory": "instrumentation/opentelemetry_grpcbox",
"name": "GRPCBox Instrumentation",
"packageName": "opentelemetry_grpcbox",
"tagPrefix": "opentelemetry-grpcbox-v",
"buildTool": "rebar3",
"language": "erlang",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"http_instrumentation": {
"workingDirectory": "utilities/opentelemetry_instrumentation_http",
"name": "HTTP Utilities",
"packageName": "opentelemetry_instrumentation_http",
"tagPrefix": "opentelemetry-instrumentation-http-v",
"buildTool": "rebar3",
"language": "erlang",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"httpoison": {
"workingDirectory": "instrumentation/opentelemetry_httpoison",
"name": "HTTPoison Instrumentation",
"packageName": "opentelemetry_httpoison",
"tagPrefix": "opentelemetry-httpoison-v",
"buildTool": "mix",
"language": "elixir",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"nebulex": {
"workingDirectory": "instrumentation/opentelemetry_nebulex",
"name": "Nebulex Instrumentation",
"packageName": "opentelemetry_nebulex",
"tagPrefix": "opentelemetry-nebulex-v",
"buildTool": "mix",
"language": "elixir",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"oban": {
"workingDirectory": "instrumentation/opentelemetry_oban",
"name": "Oban Instrumentation",
"packageName": "opentelemetry_oban",
"tagPrefix": "opentelemetry-oban-v",
"buildTool": "mix",
"language": "elixir",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"opentelemetry_telemetry": {
"workingDirectory": "utilities/opentelemetry_telemetry",
"name": "Opentelemetry Telemetry",
"packageName": "opentelemetry_telemetry",
"tagPrefix": "opentelemetry-telemetry-v",
"buildTool": "mix",
"language": "elixir-erlang",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"phoenix": {
"workingDirectory": "instrumentation/opentelemetry_phoenix",
"name": "Phoenix Instrumentation",
"packageName": "opentelemetry_phoenix",
"tagPrefix": "opentelemetry-phoenix-v",
"buildTool": "mix",
"language": "elixir",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"redix": {
"workingDirectory": "instrumentation/opentelemetry_redix",
"name": "Redix Instrumentation",
"packageName": "opentelemetry_redix",
"tagPrefix": "opentelemetry-redix-v",
"buildTool": "mix",
"language": "elixir",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"req": {
"workingDirectory": "instrumentation/opentelemetry_req",
"name": "Req Instrumentation",
"packageName": "opentelemetry_req",
"tagPrefix": "opentelemetry-req-v",
"buildTool": "mix",
"language": "elixir",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"tesla": {
"workingDirectory": "instrumentation/opentelemetry_tesla",
"name": "Tesla Instrumentation",
"packageName": "opentelemetry_tesla",
"tagPrefix": "opentelemetry-tesla-v",
"buildTool": "mix",
"language": "elixir",
"authorizedUsers": ["bryannaegele","tsloughter"]
},
"process_propagator": {
"workingDirectory": "propagators/opentelemetry_process_propagator",
"name": "Opentelemetry Process Propagator",
"packageName": "opentelemetry_process_propagator",
"tagPrefix": "opentelemetry-process-propagator-v",
"buildTool": "mix",
"language": "elixir-erlang",
"authorizedUsers": ["bryannaegele","tsloughter"]
}
}

View File

@ -0,0 +1,262 @@
name: "Publish Hex Release"
on:
workflow_dispatch:
inputs:
package:
description: "Package"
type: choice
options:
- "aws_xray"
- "cowboy"
- "dataloader"
- "ecto"
- "elli"
- "finch"
- "grpcbox"
- "http_instrumentation"
- "httpoison"
- "nebulex"
- "oban"
- "otel_telemetry"
- "phoenix"
- "process_propagator"
- "redix"
- "req"
- "tesla"
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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
- 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.buildTool)
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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
- 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 = "";
switch(needs.config.outputs.language) {
case 'elixir':
srcFilePath = `${needs.config.outputs.working_directory}/mix.exs`;
srcVersionRegex = /@version\s+"[^"]+"/;
vsnLineTemplate = `@version "${version}"`;
case 'elixir-erlang':
case 'erlang':
srcFilePath = `${needs.config.outputs.working_directory}/src/${needs.config.outputs.package_name}.app.src`;
srcVersionRegex = /{vsn:\s+"[^"]+"},/;
vsnLineTemplate = `{vsn: "${version}"},`;
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, mixVersion)) {
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@61e01a43a562a89bfc54c7f9a378ff67b03e4a21 # v1
with:
otp-version: "25.3.2.5"
elixir-version: "1.14.5"
- name: "Mix Hex Publish Dry-run"
if: ${{ needs.config.outputs.build_tool == 'mix' }}
working-directory: ${{ needs.config.outputs.working_directory }}
env:
HEX_ORG_KEY: ${{ secrets.OTEL_HEX_KEY }}
run: |
mix hex.organization auth opentelemetry --key $HEX_ORG_KEY
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_ORG_KEY: ${{ secrets.OTEL_HEX_KEY }}
run: |
rebar3 hex organization auth hexpm:opentelemetry -k $HEX_ORG_KEY
rebar3 update
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@153407881ec5c347639a548ade7d8ad1d6740e38 # v5
with:
add-paths: |
${{ needs.config.outputs.working_directory }}/mix.exs
${{ needs.config.outputs.working_directory }}/src/${{ needs.config.outputs.package_name }}.app.src
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_ORG_KEY: ${{ secrets.OTEL_HEX_KEY }}
run: |
mix hex.organization auth opentelemetry --key $HEX_ORG_KEY
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_ORG_KEY: ${{ secrets.OTEL_HEX_KEY }}
run: |
rebar3 hex organization auth hexpm:opentelemetry -k $HEX_ORG_KEY
rebar3 update
rebar3 hex publish --dry-run --yes
echo "published=true" >> $GITHUB_ENV
- name: "Pull Hex Package and Upload to Release"
if: ${{ env.releasePrepped == 'true' && inputs.action == 'publish' }}
working-directory: ${{ needs.config.outputs.working_directory }}
env:
HEX_ORG_KEY: ${{ secrets.OTEL_HEX_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
sleep 5
mix hex.organization auth opentelemetry --key $HEX_ORG_KEY
mix hex.package fetch ${{ needs.config.outputs.package_name }} ${{ env.package_version }} --organization opentelemetry
gh release upload ${{ env.gh_release_tag_name}} ${{ needs.config.outputs.package_name }}-${{ env.package_version }}.tar

View File

@ -1,11 +1,13 @@
defmodule OpentelemetryDataloader.MixProject do
use Mix.Project
@version "1.0.0"
def project do
[
app: :opentelemetry_dataloader,
description: "Trace Dataloader with OpenTelemetry.",
version: "1.0.0",
version: @version,
elixir: "~> 1.11",
start_permanent: Mix.env() == :prod,
deps: deps(),

View File

@ -1,12 +1,14 @@
defmodule OpentelemetryEcto.MixProject do
use Mix.Project
@version "1.1.1"
def project do
[
app: :opentelemetry_ecto,
description: description(),
version: "1.1.1",
elixir: "~> 1.10",
version: @version,
elixir: "~> 1.11",
start_permanent: Mix.env() == :prod,
deps: deps(),
aliases: aliases(),

View File

@ -1,12 +1,14 @@
defmodule OpentelemetryFinch.MixProject do
use Mix.Project
@version "0.2.0"
def project do
[
app: :opentelemetry_finch,
description: description(),
version: "0.2.0",
elixir: "~> 1.10",
version: @version,
elixir: "~> 1.11",
start_permanent: Mix.env() == :prod,
deps: deps(),
elixirc_paths: elixirc_paths(Mix.env()),

View File

@ -1,11 +1,13 @@
defmodule OpentelemetryNebulex.MixProject do
use Mix.Project
@version "0.1.0"
def project do
[
app: :opentelemetry_nebulex,
description: description(),
version: "0.1.0",
version: @version,
elixir: "~> 1.11",
start_permanent: Mix.env() == :prod,
deps: deps(),

View File

@ -1,11 +1,13 @@
defmodule OpentelemetryOban.MixProject do
use Mix.Project
@version "1.0.0"
def project do
[
app: :opentelemetry_oban,
version: "1.0.0",
elixir: "~> 1.10",
version: @version,
elixir: "~> 1.11",
start_permanent: Mix.env() == :prod,
deps: deps(),
docs: [

View File

@ -1,12 +1,14 @@
defmodule OpentelemetryPhoenix.MixProject do
use Mix.Project
@version "1.1.1"
def project do
[
app: :opentelemetry_phoenix,
description: description(),
version: "1.1.1",
elixir: "~> 1.10",
version: @version,
elixir: "~> 1.11",
start_permanent: Mix.env() == :prod,
dialyzer: [
plt_add_apps: [:ex_unit, :mix],

View File

@ -1,12 +1,14 @@
defmodule OpentelemetryRedix.MixProject do
use Mix.Project
@version "0.1.1"
def project do
[
app: :opentelemetry_redix,
description: description(),
version: "0.1.1",
elixir: "~> 1.10",
version: @version,
elixir: "~> 1.11",
start_permanent: Mix.env() == :prod,
deps: deps(),
elixirc_paths: elixirc_paths(Mix.env()),

View File

@ -1,11 +1,13 @@
defmodule OpentelemetryReq.MixProject do
use Mix.Project
@version "0.2.0"
def project do
[
app: :opentelemetry_req,
description: description(),
version: "0.2.0",
version: @version,
elixir: "~> 1.11",
start_permanent: Mix.env() == :prod,
deps: deps(),

View File

@ -1,11 +1,13 @@
defmodule OpentelemetryTesla.MixProject do
use Mix.Project
@version "2.3.0"
def project do
[
app: :opentelemetry_tesla,
version: "2.3.0",
elixir: "~> 1.10",
version: @version,
elixir: "~> 1.11",
start_permanent: Mix.env() == :prod,
deps: deps(),
package: package(),

View File

@ -9,7 +9,7 @@ defmodule OpentelemetryTelemetry.MixProject do
app: app,
version: to_string(Keyword.fetch!(desc, :vsn)),
description: to_string(Keyword.fetch!(desc, :description)),
elixir: "~> 1.10",
elixir: "~> 1.11",
start_permanent: Mix.env() == :prod,
deps: deps(Keyword.fetch!(config, :deps)),
name: "Opentelemetry Telemetry",