Skip to content
Merged
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
26 changes: 24 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ 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: ""
prerelease:
description: "Publish as a pre-release. Promoted to a full release once localstack-pro validates it."
type: boolean
required: false
default: false

jobs:

Expand All @@ -25,6 +38,8 @@ jobs:
build:
runs-on: ubuntu-latest
needs: test
permissions:
contents: write
steps:
- uses: actions/checkout@v7

Expand All @@ -42,10 +57,17 @@ jobs:
with:
name: aws-lambda-rie
path: bin/*
- name: Push tag
if: inputs.version != ''
run: |
git tag "${{ inputs.version }}" "$GITHUB_SHA"
git push origin "${{ inputs.version }}"

- 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: ${{ inputs.prerelease || endsWith(github.ref, '-pre') || endsWith(inputs.version, '-pre') }}
97 changes: 97 additions & 0 deletions .github/workflows/weekly-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Weekly auto-release: patch-bumps and publishes if there are new commits on localstack.
name: Weekly Release

on:
schedule:
# Fridays 06:00 UTC. The release is a pre-release until localstack-pro validates and promotes it,
# which is what gates the downstream lambda-images bump.
- 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
# Highest released version, including pre-releases still awaiting promotion, so a pending
# promotion cannot make us recompute a version whose tag already exists. The grep keeps
# RC tags (v0.0.0-rc.*) out; sort -V picks the highest version, not the newest.
latest=$(gh release list --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. Published as a
# pre-release; localstack-pro promotes it to a full release once its CI validates the version.
uses: ./.github/workflows/build.yml
with:
version: ${{ needs.version.outputs.next }}
prerelease: true

notify:
name: Report a broken weekly release
if: always() && (needs.version.result == 'failure' || needs.release.result == 'failure')
runs-on: ubuntu-latest
needs:
- version
- release
steps:
- name: "Send Message"
uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0
env:
MESSAGE: "_*Weekly RIE release failed*_ :turtle-headache::broken_heart:\n\nNo new pre-release was published, so CVE remediation is stalled until this is fixed. Investigate the failed workflow run <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|here> :mag_right:"
with:
webhook: ${{ secrets.COSY_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
blocks:
- type: "section"
text:
type: "mrkdwn"
text: "${{ env.MESSAGE }}"
19 changes: 19 additions & 0 deletions README-LOCALSTACK.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,25 @@ previous release (e.g. [`v0.1.47`](https://github.com/localstack/lambda-runtime-
> LocalStack releases — it is a manual `workflow_dispatch` that checks out `main` (the upstream
> mirror) rather than `localstack`, so it would not include the LocalStack customizations.

### Weekly auto-release

[`weekly-release.yml`](./.github/workflows/weekly-release.yml) runs every Friday at 06:00 UTC. If
`localstack` has new commits since the highest existing release, it patch-bumps the version and calls
`build.yml` to run the tests, build the binaries, push the tag, and publish the release. Together with
Renovate automerge, this is what carries dependency and CVE fixes downstream without manual work.

The release is published as a **pre-release**, and only reaches consumers once it has been validated:

1. `weekly-release.yml` publishes `vX.Y.Z`, marked as a pre-release.
2. localstack-pro opens a PR bumping `LAMBDA_RUNTIME_DEFAULT_VERSION` to that version; its CI is the
quality gate.
3. On merge, localstack-pro flips the same release to a full release through the GitHub API — no new
tag and no rebuild, so the binaries that were validated are the binaries that ship.
4. lambda-images ignores pre-releases, so Renovate only opens a bump PR there after the promotion.

Run it manually via the **Weekly Release** workflow (`workflow_dispatch`); `dryRun` reports the next
version without releasing. A failed run posts to Slack.

### RC (release candidate) pre-release

RC pre-releases let an **unmerged** PR be tested against localstack-pro CI without cutting a real
Expand Down