Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions .github/workflows/release_create-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
name: release:create-release

on:
workflow_call:
inputs:
binary_name:
type: string
required: true
description: 'Binary name(s) separated by space'
tuf_repo:
type: string
required: true
description: 'Path to binary download in release notes'
pgp_key_urls:
type: string
required: true
description: 'PGP key URL(s) separated by space (one per binary in same order)'
secrets:
TOKEN:
required: true

env:
GH_TOKEN: ${{ secrets.TOKEN }}

jobs:
create-release:
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true

- name: Get version from CHANGELOG.md
id: get_version
run: |
VERSION=$(grep -m1 '^#\+ \[[0-9]\+\.[0-9]\+\.[0-9]\+\]' CHANGELOG.md | sed -E 's/^#+ \[([0-9]+\.[0-9]+\.[0-9]+)\].*/\1/')
echo "version=$VERSION" >> $GITHUB_OUTPUT

- name: Generate notes.md
id: notes
run: |
VERSION="${{ steps.get_version.outputs.version }}"
BINARY_NAMES=(${{ inputs.binary_name }})
PGP_KEY_URLS=(${{ inputs.pgp_key_urls }})
TUF_REPOS=(${{ inputs.tuf_repo }})

if [ ${#BINARY_NAMES[@]} -ne ${#PGP_KEY_URLS[@]} ] || [ ${#BINARY_NAMES[@]} -ne ${#TUF_REPOS[@]} ]; then
echo "Error: Number of binaries (${#BINARY_NAMES[@]}), PGP keys (${#PGP_KEY_URLS[@]}) and TUF repos (${#TUF_REPOS[@]}) must match"
exit 1
fi

echo "## Changelog" > notes.md
awk -v version="$VERSION" '
$0 ~ "^#+ \\[" version "\\]" {capture=1; next}
capture && $0 ~ "^#+ \\[" && $0 !~ "^#+ \\[" version "\\]" {exit}
capture {print}
' CHANGELOG.md >> notes.md

echo -e "\n## Installation" >> notes.md
for i in "${!BINARY_NAMES[@]}"; do
BINARY_NAME="${BINARY_NAMES[i]}"
PGP_URL="${PGP_KEY_URLS[i]}"
TUF_REPO="${TUF_REPOS[i]}"

if [[ "$BINARY_NAME" == "werf" ]]; then
echo -e "\nTo install \`werf\` we strongly recommend following [these instructions](https://werf.io/getting_started/).\n" >> notes.md
fi

cat <<EOF >> notes.md
You can download \`$BINARY_NAME\` binaries from here:
* [Linux amd64](https://$TUF_REPO/targets/releases/$VERSION/linux-amd64/bin/$BINARY_NAME) ([PGP signature](https://$TUF_REPO/targets/signatures/$VERSION/linux-amd64/bin/$BINARY_NAME.sig))
* [Linux arm64](https://$TUF_REPO/targets/releases/$VERSION/linux-arm64/bin/$BINARY_NAME) ([PGP signature](https://$TUF_REPO/targets/signatures/$VERSION/linux-arm64/bin/$BINARY_NAME.sig))
* [macOS amd64](https://$TUF_REPO/targets/releases/$VERSION/darwin-amd64/bin/$BINARY_NAME) ([PGP signature](https://$TUF_REPO/targets/signatures/$VERSION/darwin-amd64/bin/$BINARY_NAME.sig))
* [macOS arm64](https://$TUF_REPO/targets/releases/$VERSION/darwin-arm64/bin/$BINARY_NAME) ([PGP signature](https://$TUF_REPO/targets/signatures/$VERSION/darwin-arm64/bin/$BINARY_NAME.sig))
* [Windows amd64](https://$TUF_REPO/targets/releases/$VERSION/windows-amd64/bin/$BINARY_NAME.exe) ([PGP signature](https://$TUF_REPO/targets/signatures/$VERSION/windows-amd64/bin/$BINARY_NAME.exe.sig))

These binaries were signed with PGP and could be verified on Linux with these commands:
\`\`\`shell
curl -sSL $PGP_URL | gpg --import
curl -sSLO "https://$TUF_REPO/targets/releases/$VERSION/linux-amd64/bin/$BINARY_NAME"
curl -sSLO "https://$TUF_REPO/targets/signatures/$VERSION/linux-amd64/bin/$BINARY_NAME.sig"
gpg --verify $BINARY_NAME.sig $BINARY_NAME
\`\`\`
EOF
done

- name: Create release
run: |
gh release create "v${{ steps.get_version.outputs.version }}" \
--title "v${{ steps.get_version.outputs.version }}" \
--prerelease \
--notes-file notes.md
50 changes: 50 additions & 0 deletions .github/workflows/release_tag-auto-create.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: tag:auto-create

on:
workflow_call:
secrets:
TOKEN:
required: true

env:
GH_TOKEN: ${{ secrets.TOKEN }}

jobs:
release:
name: Create release tag
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true

- name: Relabel closed release PR
run: |
PR_NUMBER=$(gh pr list --state closed --label "autorelease: pending" --limit 1 --json number -q '.[0].number')
if [ -n "$PR_NUMBER" ]; then
gh pr edit $PR_NUMBER --remove-label "autorelease: pending"
gh pr edit $PR_NUMBER --add-label "autorelease: tagged"
fi

- name: Get version from CHANGELOG.md
id: get_version
run: |
VERSION=$(grep -m1 '^#\+ \[[0-9]\+\.[0-9]\+\.[0-9]\+\]' CHANGELOG.md | sed -E 's/^#+ \[([0-9]+\.[0-9]+\.[0-9]+)\].*/\1/')
echo "version=$VERSION" >> $GITHUB_OUTPUT

- name: Create tag via GitHub API
run: |
TAG="v${{ steps.get_version.outputs.version }}"

if gh api repos/${{ github.repository }}/git/ref/tags/$TAG &>/dev/null; then
echo "Tag $TAG already exists. Skipping..."
exit 0
fi

COMMIT_SHA=$(git rev-parse HEAD)

gh api repos/${{ github.repository }}/git/refs \
-f ref="refs/tags/$TAG" \
-f sha="$COMMIT_SHA"
108 changes: 108 additions & 0 deletions .github/workflows/release_update-github-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
name: release:update-github-release

on:
workflow_call:
inputs:
target_group:
type: string
required: true
description: 'Group number to mark as latest (e.g., "2")'
secrets:
TOKEN:
required: true

env:
GH_TOKEN: ${{ secrets.TOKEN }}

jobs:
update-release:
runs-on: ubuntu-22.04
if: |
github.event_name == 'push' ||
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true

- name: Update GitHub releases based on trdl_channels.yaml
run: |
check_release_exists() {
local version=$1
gh release view "v$version" >/dev/null 2>&1
return $?
}

get_release_name() {
local tag=$1
gh release view "$tag" --json name | jq -r '.name'
}

process_releases() {
echo "Processing releases based on trdl_channels.yaml..."

declare -A VERSION_CHANNELS
declare -A GROUP_VERSIONS

current_group=""
while IFS= read -r line; do
if [[ $line =~ name:\ \"([^\"]+)\" ]]; then
current_group="${BASH_REMATCH[1]}"
elif [[ $line =~ name:\ ([a-z-]+) ]]; then
current_channel="${BASH_REMATCH[1]}"
elif [[ $line =~ version:\ ([0-9a-zA-Z.+-]+) ]]; then
version="${BASH_REMATCH[1]}"
key="${current_group}:${version}"
if [[ -z "${VERSION_CHANNELS[$key]}" ]]; then
VERSION_CHANNELS["$key"]="$current_channel"
GROUP_VERSIONS["$version"]="$current_group"
else
VERSION_CHANNELS["$key"]="${VERSION_CHANNELS[$key]},$current_channel"
fi
fi
done < trdl_channels.yaml

for key in "${!VERSION_CHANNELS[@]}"; do
version="${key#*:}"
group="${key%:*}"
tag="v$version"

if check_release_exists "$version"; then
channels="${VERSION_CHANNELS[$key]}"
expected_title="$tag [$channels]"
current_title=$(get_release_name "$tag")

if [[ "$current_title" != "$expected_title" ]]; then
if [[ $group == "${{ inputs.target_group }}" && $channels == *stable* ]]; then
echo "Updating $tag (group $group): stable, latest"
gh release edit "$tag" --title "$expected_title" --latest --prerelease=false || true
elif [[ $channels == *rock-solid* ]]; then
echo "Updating $tag (group $group): rock-solid, just title"
gh release edit "$tag" --title "$expected_title" --prerelease=false || true
else
echo "Updating $tag (group $group): prerelease, channels=$channels"
gh release edit "$tag" --title "$expected_title" --prerelease || true
fi
else
echo "$tag (group $group) already has correct title: $current_title"
fi
else
echo "Release $tag (group $group) not found, skipping..."
fi
done

echo "Checking for releases with outdated channel markers..."
gh release list --json name | jq -r '.[] | select(.name | test("\\[[a-zA-Z,-]+\\]")) | .name' | while read -r full_name; do
tag="${full_name%% *}"
version="${tag#v}"

[[ -n "${GROUP_VERSIONS[$version]}" ]] && continue

echo "Resetting $tag to plain version title (no channels in config)"
gh release edit "$tag" --title "$tag" --prerelease=false || true
done
}

process_releases