diff --git a/.github/files/autorelease.sh b/.github/files/autorelease.sh index cf26c71e..45e6a754 100755 --- a/.github/files/autorelease.sh +++ b/.github/files/autorelease.sh @@ -2,32 +2,42 @@ set -eo pipefail +: "${GH_TOKEN:?Build argument needs to be set and non-empty.}" : "${GITHUB_REF:?Build argument needs to be set and non-empty.}" : "${GITHUB_SHA:?Build argument needs to be set and non-empty.}" -: "${API_TOKEN_GITHUB:?Build argument needs to be set and non-empty.}" -: "${GITHUB_API_URL:?Build argument needs to be set and non-empty.}" -: "${GITHUB_REPOSITORY:?Build argument needs to be set and non-empty.}" -## Determine tag -if [[ ! "$GITHUB_REF" =~ ^refs/tags/v?[0-9]+(\.[0-9]+)+(-[a-z0-9._-]+)?$ ]]; then - echo "::error::Expected GITHUB_REF like \`refs/tags/v1.2.3\` or \`refs/tags/1.2.3\`, got \`$GITHUB_REF\`" +if [[ ! -f composer.json ]]; then + echo '::error::No composer.json. Did it get excluded from the mirror?' exit 1 fi -TAG="${GITHUB_REF#refs/tags/}" -## Check for alphas -if [[ "$TAG" =~ -(alpha|a\.[0-9]*[02468])$ ]]; then - echo "Not creating a release for alpha version $TAG" - exit 0 -fi -echo "Creating release for $TAG" +## Determine tag +ROLLING_MODE= +if [[ "$GITHUB_REF" =~ ^refs/tags/v?[0-9]+(\.[0-9]+)+(-[a-z0-9._-]+)?$ ]]; then + TAG="${GITHUB_REF#refs/tags/}" -## Determine slug and title format. -if [[ ! -f composer.json ]]; then - echo '::error::No composer.json. Did it get excluded from the mirror?' + ## Check for alphas + if [[ "$TAG" =~ -(alpha|a\.[0-9]*[02468])$ ]]; then + echo "Not creating a release for alpha version $TAG" + exit 0 + fi +elif [[ "$GITHUB_REF" == "refs/heads/trunk" ]]; then + if ! jq -e '.extra.autorelease["rolling-release"]? // false' composer.json > /dev/null; then + echo "::notice::Skipping trunk release because autorelease rolling mode is not enabled." + exit 0 + fi + ROLLING_MODE=true + CURRENT_VER=$( sed -nEe 's/^## \[?([^]]*)\]? - .*/\1/;T;p;q' CHANGELOG.md || true ) + GIT_SUFFIX=$( git log -1 --format=%h . ) + TAG="$CURRENT_VER+rolling.$GIT_SUFFIX" +else + echo "::error::Expected GITHUB_REF like \`refs/tags/v1.2.3\` or \`refs/tags/1.2.3\` or \`refs/heads/trunk\` for rolling releases, got \`$GITHUB_REF\`" exit 1 fi +echo "Creating release for $TAG" + +## Determine slug and title format. SLUG="$(jq -r '.extra.autorelease.slug? // .extra["wp-plugin-slug"] // .extra["beta-plugin-slug"] // ( .name | sub( "^.*/"; "" ) )' composer.json)" if [[ -z "$SLUG" ]]; then echo '::error::Failed to get slug from composer.json.' @@ -48,76 +58,75 @@ echo "::group::Creating $SLUG.zip" git archive -v --output="$SLUG.zip" --prefix="$SLUG/" HEAD 2>&1 echo "::endgroup::" -## Create the release note. -# Extract the changelog section. -echo "::group::Extracting release notes" -if [[ ! -f CHANGELOG.md ]]; then - echo '::endgroup::' - echo '::error::No CHANGELOG.md for release notes.' - exit 1 -fi -SCRIPT=" - /^## \\[?$(sed 's/[.\[\]\\*^$\/()+?{}|]/\\&/g' <<<"${TAG#v}")\\]? - / { - bc +if [[ -z "$ROLLING_MODE" ]]; then + ## Create the release note. + # Extract the changelog section. + echo "::group::Extracting release notes" + if [[ ! -f CHANGELOG.md ]]; then + echo '::endgroup::' + echo '::error::No CHANGELOG.md for release notes.' + exit 1 + fi + SCRIPT=" + /^## \\[?$(sed 's/[.\[\]\\*^$\/()+?{}|]/\\&/g' <<<"${TAG#v}")\\]? - / { + bc + :a + n + /^## / { + q + } + :c + s/^## \[([^]]+)\]/## \1/ + p + ba + } + " + ENTRY=$(sed -n -E -e "$SCRIPT" CHANGELOG.md) + if [[ -z "$ENTRY" ]]; then + echo '::endgroup::' + echo "::error::Failed to find section for ${TAG#v} in CHANGELOG.md" + exit 1 + fi + + # Strip unwanted sections. + SCRIPT=" :a - n - /^## / { - q + /^### .* This section will not be copied to readme\.txt/ { + :b + n + /^#/ ba + bb } - :c - s/^## \[([^]]+)\]/## \1/ p - ba - } -" -ENTRY=$(sed -n -E -e "$SCRIPT" CHANGELOG.md) -if [[ -z "$ENTRY" ]]; then - echo '::endgroup::' - echo "::error::Failed to find section for ${TAG#v} in CHANGELOG.md" - exit 1 + " + ENTRY=$(sed -n -E -e "$SCRIPT" <<<"$ENTRY") + + echo "Release notes:" + echo "-----" + echo "$ENTRY" + echo "-----" + echo "::endgroup::" +else + ## Using a brief explanation for the rolling release note. + ENTRY="### Rolling release based on the trunk branch." +fi + +if [[ -n "$ROLLING_MODE" ]]; then + echo "::group::Deleting stale rolling release" + + for R in $( gh release list --limit 100 --json tagName --jq '.[].tagName | select( contains( "rolling" ) )' ); do + echo "Found $R, deleting" + gh release delete "$R" --cleanup-tag --yes + done + + echo "::endgroup::" fi -# Strip unwanted sections. -SCRIPT=" - :a - /^### .* This section will not be copied to readme\.txt/ { - :b - n - /^#/ ba - bb - } - p -" -ENTRY=$(sed -n -E -e "$SCRIPT" <<<"$ENTRY") - -echo "Release notes:" -echo "-----" -echo "$ENTRY" -echo "-----" -echo "::endgroup::" echo "::group::Creating release" -curl -v -L \ - --write-out '%{response_code}' \ - --output out.json \ - --request POST \ - --header "authorization: Bearer $API_TOKEN_GITHUB" \ - --header 'content-type: application/json' \ - --header 'accept: application/vnd.github.v3+json' \ - --url "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases" \ - --data "$(jq -n --arg tag "$TAG" --arg sha "$GITHUB_SHA" --arg title "$TITLE" --arg body "$ENTRY" '{ tag_name: $tag, target_commitish: $sha, name: $title, body: $body}')" \ - 2>&1 > code.txt -cat out.json -echo -[[ "$(&1 echo "::endgroup::" diff --git a/.github/workflows/autorelease.yml b/.github/workflows/autorelease.yml index 7fb76b4f..5109e151 100644 --- a/.github/workflows/autorelease.yml +++ b/.github/workflows/autorelease.yml @@ -9,6 +9,8 @@ on: - 'v?[0-9]+.[0-9]+.[0-9]+-*' - 'v?[0-9]+.[0-9]+.[0-9]+.[0-9]+' - 'v?[0-9]+.[0-9]+.[0-9]+.[0-9]+-*' + branches: + - 'trunk' jobs: publish: @@ -18,5 +20,5 @@ jobs: - uses: actions/checkout@v4 - name: Create release env: - API_TOKEN_GITHUB: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: ./.github/files/autorelease.sh