Skip to content
Open
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
70 changes: 70 additions & 0 deletions .github/actions/prepare-versioned-release/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Prepare versioned release
description: Create or verify the immutable version tag for the checked-out commit.

inputs:
source-directory:
description: Repository directory that contains the release source.
required: false
default: .

outputs:
release_tag:
description: The immutable tag for the version in pubspec.yaml.
value: ${{ steps.prepare.outputs.release_tag }}

runs:
using: composite
steps:
- id: prepare
shell: bash
run: |
set -euo pipefail
cd "${{ inputs.source-directory }}"

version=$(awk '$1 == "version:" { print $2; exit }' open_wearable/pubspec.yaml)
version=${version//\"/}
version=${version//\'/}
version_pattern='^([0-9]+)\.([0-9]+)\.([0-9]+)(\+[0-9]+)?$'
if ! [[ "$version" =~ $version_pattern ]]; then
echo "::error::Version '$version' must use major.minor.patch with an optional numeric +build suffix."
exit 1
fi

public_version=${version%%+*}
release_tag="v${public_version}"
released_sha=$(git rev-parse HEAD)
version_notes_path="open_wearable/release_notes/${public_version}/default.txt"
fallback_notes_path="open_wearable/release_notes/default.txt"
notes_path="$version_notes_path"
if [ ! -s "$notes_path" ]; then
notes_path="$fallback_notes_path"
echo "Using generic release notes because $version_notes_path is missing."
fi
if [ ! -s "$notes_path" ]; then
echo "::error::Missing version-specific release notes at $version_notes_path and fallback release notes at $fallback_notes_path."
exit 1
fi

git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

if git ls-remote --exit-code --tags origin "refs/tags/$release_tag" >/dev/null 2>&1; then
git fetch origin "refs/tags/$release_tag:refs/tags/$release_tag"
tagged_sha=$(git rev-list -n 1 "$release_tag")
if [ "$tagged_sha" != "$released_sha" ]; then
echo "::error::Tag $release_tag already points to $tagged_sha, not $released_sha. Select $release_tag as the release ref to use the existing version."
exit 1
fi
else
git tag -a "$release_tag" "$released_sha" -m "OpenWearable $public_version"
if ! git push origin "$release_tag"; then
git fetch --force origin "refs/tags/$release_tag:refs/tags/$release_tag"
tagged_sha=$(git rev-list -n 1 "$release_tag")
if [ "$tagged_sha" != "$released_sha" ]; then
echo "::error::Tag $release_tag already points to $tagged_sha, not $released_sha. Select $release_tag as the release ref to use the existing version."
exit 1
fi
fi
fi

echo "release_tag=$release_tag" >> "$GITHUB_OUTPUT"
69 changes: 69 additions & 0 deletions .github/actions/publish-versioned-release/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Publish versioned release
description: Create or update the GitHub Release for a verified release tag.

inputs:
source-directory:
description: Repository directory checked out at the release tag.
required: false
default: .
release-tag:
description: Immutable release tag to publish.
required: true

runs:
using: composite
steps:
- shell: bash
run: |
set -euo pipefail
cd "${{ inputs.source-directory }}"

version=$(awk '$1 == "version:" { print $2; exit }' open_wearable/pubspec.yaml)
version=${version//\"/}
version=${version//\'/}
public_version=${version%%+*}
expected_tag="v${public_version}"
release_tag="${{ inputs.release-tag }}"

if [ "$release_tag" != "$expected_tag" ]; then
echo "::error::Tag $release_tag does not match pubspec version $public_version."
exit 1
fi

tagged_sha=$(git rev-list -n 1 "$release_tag")
if [ "$tagged_sha" != "$(git rev-parse HEAD)" ]; then
echo "::error::Release source is not checked out at $release_tag."
exit 1
fi

version_notes_path="open_wearable/release_notes/${public_version}/default.txt"
fallback_notes_path="open_wearable/release_notes/default.txt"
notes_path="$version_notes_path"
if [ ! -s "$notes_path" ]; then
notes_path="$fallback_notes_path"
echo "Using generic release notes because $version_notes_path is missing."
fi
if [ ! -s "$notes_path" ]; then
echo "::error::Missing version-specific release notes at $version_notes_path and fallback release notes at $fallback_notes_path."
exit 1
fi

if gh release view "$release_tag" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
gh release edit "$release_tag" \
--repo "$GITHUB_REPOSITORY" \
--title "OpenWearable $public_version" \
--notes-file "$notes_path"
else
if ! gh release create "$release_tag" \
--repo "$GITHUB_REPOSITORY" \
--verify-tag \
--title "OpenWearable $public_version" \
--notes-file "$notes_path"; then
# Another successful platform workflow may have published the
# release between the view and create calls.
gh release edit "$release_tag" \
--repo "$GITHUB_REPOSITORY" \
--title "OpenWearable $public_version" \
--notes-file "$notes_path"
fi
fi
Loading
Loading