name: Release on: push: tags: ["v*"] jobs: release: runs-on: codeberg-small steps: - uses: https://data.forgejo.org/actions/checkout@v4 - uses: https://github.com/ruby/setup-ruby@v1 with: ruby-version: "3.4" bundler-cache: true - name: Resolve and verify version id: version env: REF: ${{ forgejo.ref }} run: | set -euo pipefail VERSION="${REF##*/}" if [[ ! "$VERSION" =~ ^v[0-9]+(\.[0-9]+){0,2}([-+].*)?$ ]]; then echo "ERROR: expected a semver tag like v1.2.3, got: '$VERSION' (ref: '$REF')" exit 1 fi VERSION_NO_V="${VERSION#v}" GEM_VERSION="$(ruby -Ilib -rvolumen/version -e 'print Volumen::VERSION')" if [ "$VERSION_NO_V" != "$GEM_VERSION" ]; then echo "ERROR: tag ${VERSION} does not match Volumen::VERSION (${GEM_VERSION})" exit 1 fi echo "version_no_v=${VERSION_NO_V}" >> "$FORGEJO_OUTPUT" - name: Quality gate run: | set -euo pipefail bundle exec rubocop bundle exec rake test - name: Build gem env: VERSION_NO_V: ${{ steps.version.outputs.version_no_v }} run: | set -euo pipefail gem build volumen.gemspec --output "volumen-${VERSION_NO_V}.gem" ls -lh "volumen-${VERSION_NO_V}.gem" - name: Extract CHANGELOG section env: VERSION_NO_V: ${{ steps.version.outputs.version_no_v }} run: | set -euo pipefail sed -n "/^## \[${VERSION_NO_V}\] /,/^## \[/p" CHANGELOG.md \ | sed '$d' \ | tail -n +2 \ > release-body.md if [ ! -s release-body.md ]; then echo "ERROR: no CHANGELOG section found for ${VERSION_NO_V}" echo "Expected a heading like: ## [${VERSION_NO_V}] — YYYY-MM-DD" exit 1 fi echo "Release body preview:" head -n 20 release-body.md - name: Create release id: create env: FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }} run: | set -euo pipefail BODY="$(ruby -rjson -e 'print JSON.generate($stdin.read)' < release-body.md)" response="$(curl -sS -w '\n%{http_code}' \ -H "Authorization: token ${FORGEJO_TOKEN}" \ -H "Content-Type: application/json" \ -X POST \ "${FORGEJO_SERVER_URL}/api/v1/repos/${FORGEJO_REPOSITORY}/releases" \ -d "{ \"tag_name\": \"${FORGEJO_REF_NAME}\", \"name\": \"${FORGEJO_REF_NAME}\", \"body\": ${BODY}, \"draft\": false, \"prerelease\": false }")" http_code="$(echo "$response" | tail -1)" payload="$(echo "$response" | sed '$d')" echo "HTTP ${http_code}" if [ "$http_code" != "201" ]; then echo "Failed to create release: ${payload}" exit 1 fi RELEASE_ID="$(echo "$payload" | ruby -rjson -e 'print JSON.parse($stdin.read)["id"]')" echo "Created release ID=${RELEASE_ID}" echo "release_id=${RELEASE_ID}" >> "$FORGEJO_OUTPUT" - name: Upload gem asset env: FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }} VERSION_NO_V: ${{ steps.version.outputs.version_no_v }} RELEASE_ID: ${{ steps.create.outputs.release_id }} run: | set -euo pipefail GEM="volumen-${VERSION_NO_V}.gem" http_code="$(curl -sS -o /dev/null -w '%{http_code}' \ -H "Authorization: token ${FORGEJO_TOKEN}" \ -H "Content-Type: application/octet-stream" \ -X POST \ --data-binary "@${GEM}" \ "${FORGEJO_SERVER_URL}/api/v1/repos/${FORGEJO_REPOSITORY}/releases/${RELEASE_ID}/assets?name=${GEM}")" echo "HTTP ${http_code}" if [ "$http_code" != "201" ]; then echo "Failed to upload ${GEM}" exit 1 fi echo "Release ${FORGEJO_REF_NAME} is live with ${GEM}."