diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2f76ee6..ba60244 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,6 +6,14 @@ on: tags: v*.* pull_request: branches: [ localstack ] + # Callable by weekly-release.yml; publishes a release when `version` is set. + workflow_call: + inputs: + version: + description: "Release version to tag and publish (e.g. v0.2.1). When set, a release is published." + type: string + required: false + default: "" jobs: @@ -25,6 +33,8 @@ jobs: build: runs-on: ubuntu-latest needs: test + permissions: + contents: write steps: - uses: actions/checkout@v7 @@ -44,8 +54,9 @@ jobs: path: bin/* - name: Release binaries uses: softprops/action-gh-release@v3 - if: startsWith(github.ref, 'refs/tags/') + if: startsWith(github.ref, 'refs/tags/') || inputs.version != '' with: + tag_name: ${{ inputs.version || github.ref_name }} files: bin/* generate_release_notes: true - prerelease: ${{ endsWith(github.ref, '-pre') }} + prerelease: ${{ endsWith(github.ref, '-pre') || endsWith(inputs.version, '-pre') }} diff --git a/.github/workflows/weekly-release.yml b/.github/workflows/weekly-release.yml new file mode 100644 index 0000000..50e1988 --- /dev/null +++ b/.github/workflows/weekly-release.yml @@ -0,0 +1,70 @@ +# Weekly auto-release: patch-bumps and publishes if there are new commits on localstack. +name: Weekly Release + +on: + schedule: + # Fridays 06:00 UTC: ahead of lambda-images' Mon 13:00 UTC rebuild so Renovate can bump downstream pins first. + - cron: '0 6 * * 5' + workflow_dispatch: + inputs: + dryRun: + description: "Compute the next version but do not release." + type: boolean + default: false + +permissions: + contents: read + +jobs: + version: + runs-on: ubuntu-latest + outputs: + should_release: ${{ steps.ver.outputs.should_release }} + next: ${{ steps.ver.outputs.next }} + steps: + - uses: actions/checkout@v7 + with: + ref: localstack + fetch-depth: 0 + + - name: Determine next version + id: ver + env: + GH_TOKEN: ${{ github.token }} + run: | + git fetch --tags --force + # Latest published release (same source as downstream Renovate); sort -V for highest version, not newest. + latest=$(gh release list --exclude-pre-releases --exclude-drafts \ + --json tagName -q '.[].tagName' \ + | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n1) + if [ -z "$latest" ]; then + echo "::error::No published vX.Y.Z release found to bump from." && exit 1 + fi + count=$(git rev-list "${latest}..HEAD" --count) + ver=${latest#v} + IFS=. read -r major minor patch <<< "$ver" + next="v${major}.${minor}.$((patch + 1))" + should_release=true + if [ "$count" = "0" ]; then + should_release=false + echo "No new commits since $latest; nothing to release." + fi + if [ "${{ inputs.dryRun }}" = "true" ]; then + should_release=false + echo "dryRun requested; not releasing." + fi + { + echo "next=$next" + echo "should_release=$should_release" + } >> "$GITHUB_OUTPUT" + echo "Latest release: $latest | new commits since: $count | next: $next | release: $should_release" + + release: + needs: version + if: needs.version.outputs.should_release == 'true' + permissions: + contents: write + # Reuse build.yml's test -> build -> release path with the computed version. + uses: ./.github/workflows/build.yml + with: + version: ${{ needs.version.outputs.next }}