Meshtastic-Android/.github/workflows/create-or-promote-release.yml

146 lines
5.3 KiB
YAML

name: Create or Promote Release
on:
workflow_dispatch:
inputs:
base_version:
description: 'Base version for the release (e.g., 2.3.0)'
required: true
channel:
description: 'The channel to create a release for or promote to'
required: true
type: choice
options:
- internal
- closed
- open
- production
dry_run:
description: 'If true, calculates the tag but does not push it or start the release'
required: true
type: boolean
default: false
permissions:
contents: write
pull-requests: read
id-token: write
attestations: write
jobs:
determine-tags:
runs-on: ubuntu-latest
outputs:
tag_to_process: ${{ steps.calculate_tags.outputs.tag_to_process }}
release_name: ${{ steps.calculate_tags.outputs.release_name }}
final_tag: ${{ steps.calculate_tags.outputs.final_tag }}
from_channel: ${{ steps.calculate_tags.outputs.from_channel }}
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Calculate tags
id: calculate_tags
run: |
BASE_VERSION="${{ inputs.base_version }}"
CHANNEL="${{ inputs.channel }}"
if [[ "$CHANNEL" == "internal" ]]; then
# This is a new build, create a new internal tag
LATEST_TAG=$(git tag --list "v${BASE_VERSION}-internal.*" --sort=-v:refname | head -n 1)
if [ -z "$LATEST_TAG" ]; then
INCREMENT=1
else
INCREMENT=$(echo "$LATEST_TAG" | sed -n "s/.*-internal\.\([0-9]*\)/\1/p" | awk '{print $1+1}')
fi
NEW_TAG="v${BASE_VERSION}-internal.${INCREMENT}"
echo "Calculated new tag: $NEW_TAG"
echo "tag_to_process=$NEW_TAG" >> $GITHUB_OUTPUT
echo "release_name=$NEW_TAG" >> $GITHUB_OUTPUT
echo "final_tag=$NEW_TAG" >> $GITHUB_OUTPUT
else
# This is a promotion, find the latest tag from the previous channel to promote
FROM_CHANNEL="internal"
if [[ "$CHANNEL" == "open" ]]; then
FROM_CHANNEL="closed"
elif [[ "$CHANNEL" == "production" ]]; then
FROM_CHANNEL="open"
fi
LATEST_TAG_TO_PROMOTE=$(git tag --list "v${BASE_VERSION}-${FROM_CHANNEL}.*" --sort=-v:refname | head -n 1)
if [ -z "$LATEST_TAG_TO_PROMOTE" ]; then
echo "::error::No ${FROM_CHANNEL} release found for base version ${BASE_VERSION} to promote."
exit 1
fi
echo "Found latest ${FROM_CHANNEL} tag to promote: $LATEST_TAG_TO_PROMOTE"
# Calculate the increment for the TARGET channel
if [[ "$CHANNEL" != "production" ]]; then
LATEST_CHANNEL_TAG=$(git tag --list "v${BASE_VERSION}-${CHANNEL}.*" --sort=-v:refname | head -n 1)
if [ -z "$LATEST_CHANNEL_TAG" ]; then
INCREMENT=1
else
INCREMENT=$(echo "$LATEST_CHANNEL_TAG" | sed -n "s/.*-${CHANNEL}\.\([0-9]*\)/\1/p" | awk '{print $1+1}')
fi
NEW_TAG="v${BASE_VERSION}-${CHANNEL}.${INCREMENT}"
else
# Production is special, it has no increment
NEW_TAG="v${BASE_VERSION}"
fi
echo "New release name will be: $NEW_TAG"
echo "Final tag will be: $NEW_TAG"
echo "from_channel=${FROM_CHANNEL}" >> $GITHUB_OUTPUT
echo "tag_to_process=${LATEST_TAG_TO_PROMOTE}" >> $GITHUB_OUTPUT
echo "release_name=${NEW_TAG}" >> $GITHUB_OUTPUT
echo "final_tag=${NEW_TAG}" >> $GITHUB_OUTPUT
fi
shell: bash
- name: Create and push new tag
if: ${{ !inputs.dry_run }}
env:
GH_TOKEN: ${{ github.token }}
run: |
FINAL_TAG="${{ steps.calculate_tags.outputs.final_tag }}"
if [[ "${{ inputs.channel }}" == "internal" ]]; then
# For internal, tag the current HEAD. tag_to_process and final_tag are the same.
git tag $FINAL_TAG
else
# For promotions, create the new tag pointing to the same commit as the old tag.
TAG_TO_PROCESS="${{ steps.calculate_tags.outputs.tag_to_process }}"
git tag $FINAL_TAG $TAG_TO_PROCESS
fi
git push origin $FINAL_TAG
shell: bash
call-release-workflow:
if: ${{ !inputs.dry_run && inputs.channel == 'internal' }}
needs: determine-tags
uses: ./.github/workflows/release.yml
with:
tag_name: ${{ needs.determine-tags.outputs.tag_to_process }}
channel: ${{ inputs.channel }}
base_version: ${{ inputs.base_version }}
secrets: inherit
call-promote-workflow:
if: ${{ !inputs.dry_run && inputs.channel != 'internal' }}
needs: determine-tags
uses: ./.github/workflows/promote.yml
with:
tag_name: ${{ needs.determine-tags.outputs.tag_to_process }}
release_name: ${{ needs.determine-tags.outputs.release_name }}
final_tag: ${{ needs.determine-tags.outputs.final_tag }}
channel: ${{ inputs.channel }}
base_version: ${{ inputs.base_version }}
from_channel: ${{ needs.determine-tags.outputs.from_channel }}
secrets: inherit