From 4725fe812ab55075e24e4d44a3d6ee3f44bea2a5 Mon Sep 17 00:00:00 2001 From: "mkeeler@launchdarkly.com" Date: Tue, 31 Mar 2026 21:21:31 +0000 Subject: [PATCH 01/12] ci: use draft releases to support immutable GitHub releases --- .../manual-sdk-release-artifacts.yml | 72 ++-- .github/workflows/release-please.yml | 310 ++++++++++++------ release-please-config.json | 1 + 3 files changed, 242 insertions(+), 141 deletions(-) diff --git a/.github/workflows/manual-sdk-release-artifacts.yml b/.github/workflows/manual-sdk-release-artifacts.yml index a265bf2d5..7ca28cb80 100644 --- a/.github/workflows/manual-sdk-release-artifacts.yml +++ b/.github/workflows/manual-sdk-release-artifacts.yml @@ -40,10 +40,10 @@ jobs: # Each of the platforms for which release-artifacts need generated. os: [ ubuntu-22.04, windows-2022, macos-15-large ] runs-on: ${{ matrix.os }} - outputs: - hashes-linux: ${{ steps.release-sdk.outputs.hashes-linux }} - hashes-windows: ${{ steps.release-sdk.outputs.hashes-windows }} - hashes-macos: ${{ steps.release-sdk.outputs.hashes-macos }} + permissions: + contents: write + attestations: write + id-token: write steps: # https://github.com/actions/checkout/releases/tag/v4.3.0 - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 @@ -58,12 +58,32 @@ jobs: github_token: ${{secrets.GITHUB_TOKEN}} sdk_path: ${{ needs.split-input.outputs.sdk_path}} sdk_cmake_target: ${{ needs.split-input.outputs.sdk_cmake_target}} + - name: Generate checksums file + env: + HASHES_LINUX: ${{ steps.release-sdk.outputs.hashes-linux }} + HASHES_WINDOWS: ${{ steps.release-sdk.outputs.hashes-windows }} + HASHES_MACOS: ${{ steps.release-sdk.outputs.hashes-macos }} + run: | + if [ -n "${HASHES_LINUX}" ]; then + echo "${HASHES_LINUX}" | base64 -d > checksums.txt + elif [ -n "${HASHES_WINDOWS}" ]; then + echo "${HASHES_WINDOWS}" | base64 -d > checksums.txt + elif [ -n "${HASHES_MACOS}" ]; then + echo "${HASHES_MACOS}" | base64 -d > checksums.txt + fi + shell: bash + - name: Attest build provenance + uses: actions/attest@v4 + with: + subject-checksums: checksums.txt release-sdk-mac-arm64: needs: split-input runs-on: macos-15 - outputs: - hashes-macos-arm64: ${{ steps.release-sdk.outputs.hashes-macos }} + permissions: + contents: write + attestations: write + id-token: write steps: # https://github.com/actions/checkout/releases/tag/v4.3.0 - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 @@ -78,33 +98,13 @@ jobs: sdk_path: ${{ needs.split-input.outputs.sdk_path}} sdk_cmake_target: ${{ needs.split-input.outputs.sdk_cmake_target}} mac_artifact_arch: 'arm64' - - release-sdk-provenance: - needs: [ 'release-sdk' ] - strategy: - matrix: - # Generates a combined attestation for each platform - os: [ linux, windows, macos ] - permissions: - actions: read - id-token: write - contents: write - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 - with: - base64-subjects: "${{ needs.release-sdk.outputs[format('hashes-{0}', matrix.os)] }}" - upload-assets: true - upload-tag-name: ${{ inputs.tag }} - provenance-name: ${{ format('{0}-multiple-provenance.intoto.jsonl', matrix.os) }} - - release-sdk-mac-arm64-provenance: - needs: [ 'release-sdk-mac-arm64' ] - permissions: - actions: read - id-token: write - contents: write - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 - with: - base64-subjects: "${{ needs.release-sdk-mac-arm64.outputs.hashes-macos-arm64 }}" - upload-assets: true - upload-tag-name: ${{ inputs.tag }} - provenance-name: 'macos-arm64-multiple-provenance.intoto.jsonl' + - name: Generate checksums file + env: + HASHES: ${{ steps.release-sdk.outputs.hashes-macos }} + run: | + echo "${HASHES}" | base64 -d > checksums.txt + shell: bash + - name: Attest build provenance + uses: actions/attest@v4 + with: + subject-checksums: checksums.txt diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index f6af1d0bb..5000c6d2e 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -26,18 +26,70 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} + create-tags: + needs: ['release-please'] + if: >- + needs.release-please.outputs.package-client-released == 'true' || + needs.release-please.outputs.package-server-released == 'true' || + needs.release-please.outputs.package-server-redis-released == 'true' || + needs.release-please.outputs.package-server-otel-released == 'true' + runs-on: ubuntu-22.04 + permissions: + contents: write + steps: + # https://github.com/actions/checkout/releases/tag/v4.3.0 + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 + with: + fetch-depth: 0 + - name: Create release tags + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CLIENT_TAG: ${{ needs.release-please.outputs.package-client-tag }} + SERVER_TAG: ${{ needs.release-please.outputs.package-server-tag }} + SERVER_REDIS_TAG: ${{ needs.release-please.outputs.package-server-redis-tag }} + SERVER_OTEL_TAG: ${{ needs.release-please.outputs.package-server-otel-tag }} + CLIENT_RELEASED: ${{ needs.release-please.outputs.package-client-released }} + SERVER_RELEASED: ${{ needs.release-please.outputs.package-server-released }} + SERVER_REDIS_RELEASED: ${{ needs.release-please.outputs.package-server-redis-released }} + SERVER_OTEL_RELEASED: ${{ needs.release-please.outputs.package-server-otel-released }} + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + for pair in \ + "${CLIENT_RELEASED}:${CLIENT_TAG}" \ + "${SERVER_RELEASED}:${SERVER_TAG}" \ + "${SERVER_REDIS_RELEASED}:${SERVER_REDIS_TAG}" \ + "${SERVER_OTEL_RELEASED}:${SERVER_OTEL_TAG}"; do + + RELEASED="${pair%%:*}" + TAG="${pair#*:}" + + if [ "${RELEASED}" != "true" ] || [ -z "${TAG}" ]; then + continue + fi + + if gh api "repos/${{ github.repository }}/git/ref/tags/${TAG}" >/dev/null 2>&1; then + echo "Tag ${TAG} already exists, skipping creation." + else + echo "Creating tag ${TAG}." + git tag "${TAG}" + git push origin "${TAG}" + fi + done + release-client: strategy: matrix: # Each of the platforms for which release-artifacts need generated. os: [ ubuntu-22.04, windows-2022, macos-15-large ] runs-on: ${{ matrix.os }} - needs: [ 'release-please' ] + needs: [ 'release-please', 'create-tags' ] if: ${{ needs.release-please.outputs.package-client-released == 'true'}} - outputs: - hashes-linux: ${{ steps.release-client.outputs.hashes-linux }} - hashes-windows: ${{ steps.release-client.outputs.hashes-windows }} - hashes-macos: ${{ steps.release-client.outputs.hashes-macos }} + permissions: + contents: write + attestations: write + id-token: write steps: # https://github.com/actions/checkout/releases/tag/v4.3.0 - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 @@ -50,13 +102,33 @@ jobs: github_token: ${{secrets.GITHUB_TOKEN}} sdk_path: 'libs/client-sdk' sdk_cmake_target: 'launchdarkly-cpp-client' + - name: Generate checksums file + env: + HASHES_LINUX: ${{ steps.release-client.outputs.hashes-linux }} + HASHES_WINDOWS: ${{ steps.release-client.outputs.hashes-windows }} + HASHES_MACOS: ${{ steps.release-client.outputs.hashes-macos }} + run: | + if [ -n "${HASHES_LINUX}" ]; then + echo "${HASHES_LINUX}" | base64 -d > checksums.txt + elif [ -n "${HASHES_WINDOWS}" ]; then + echo "${HASHES_WINDOWS}" | base64 -d > checksums.txt + elif [ -n "${HASHES_MACOS}" ]; then + echo "${HASHES_MACOS}" | base64 -d > checksums.txt + fi + shell: bash + - name: Attest build provenance + uses: actions/attest@v4 + with: + subject-checksums: checksums.txt release-client-mac-arm64: runs-on: macos-15 - needs: [ 'release-please' ] + needs: [ 'release-please', 'create-tags' ] if: ${{ needs.release-please.outputs.package-client-released == 'true'}} - outputs: - hashes-macos-arm64: ${{ steps.release-client.outputs.hashes-macos }} + permissions: + contents: write + attestations: write + id-token: write steps: # https://github.com/actions/checkout/releases/tag/v4.3.0 - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 @@ -69,6 +141,16 @@ jobs: sdk_path: 'libs/client-sdk' sdk_cmake_target: 'launchdarkly-cpp-client' mac_artifact_arch: 'arm64' + - name: Generate checksums file + env: + HASHES: ${{ steps.release-client.outputs.hashes-macos }} + run: | + echo "${HASHES}" | base64 -d > checksums.txt + shell: bash + - name: Attest build provenance + uses: actions/attest@v4 + with: + subject-checksums: checksums.txt release-server: strategy: @@ -76,12 +158,12 @@ jobs: # Each of the platforms for which release-artifacts need generated. os: [ ubuntu-22.04, windows-2022, macos-15-large ] runs-on: ${{ matrix.os }} - needs: [ 'release-please' ] + needs: [ 'release-please', 'create-tags' ] if: ${{ needs.release-please.outputs.package-server-released == 'true'}} - outputs: - hashes-linux: ${{ steps.release-server.outputs.hashes-linux }} - hashes-windows: ${{ steps.release-server.outputs.hashes-windows }} - hashes-macos: ${{ steps.release-server.outputs.hashes-macos }} + permissions: + contents: write + attestations: write + id-token: write steps: # https://github.com/actions/checkout/releases/tag/v4.3.0 - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 @@ -94,13 +176,33 @@ jobs: github_token: ${{secrets.GITHUB_TOKEN}} sdk_path: 'libs/server-sdk' sdk_cmake_target: 'launchdarkly-cpp-server' + - name: Generate checksums file + env: + HASHES_LINUX: ${{ steps.release-server.outputs.hashes-linux }} + HASHES_WINDOWS: ${{ steps.release-server.outputs.hashes-windows }} + HASHES_MACOS: ${{ steps.release-server.outputs.hashes-macos }} + run: | + if [ -n "${HASHES_LINUX}" ]; then + echo "${HASHES_LINUX}" | base64 -d > checksums.txt + elif [ -n "${HASHES_WINDOWS}" ]; then + echo "${HASHES_WINDOWS}" | base64 -d > checksums.txt + elif [ -n "${HASHES_MACOS}" ]; then + echo "${HASHES_MACOS}" | base64 -d > checksums.txt + fi + shell: bash + - name: Attest build provenance + uses: actions/attest@v4 + with: + subject-checksums: checksums.txt release-server-mac-arm64: runs-on: macos-15 - needs: [ 'release-please' ] + needs: [ 'release-please', 'create-tags' ] if: ${{ needs.release-please.outputs.package-server-released == 'true'}} - outputs: - hashes-macos-arm64: ${{ steps.release-server.outputs.hashes-macos }} + permissions: + contents: write + attestations: write + id-token: write steps: # https://github.com/actions/checkout/releases/tag/v4.3.0 - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 @@ -113,6 +215,16 @@ jobs: sdk_path: 'libs/server-sdk' sdk_cmake_target: 'launchdarkly-cpp-server' mac_artifact_arch: 'arm64' + - name: Generate checksums file + env: + HASHES: ${{ steps.release-server.outputs.hashes-macos }} + run: | + echo "${HASHES}" | base64 -d > checksums.txt + shell: bash + - name: Attest build provenance + uses: actions/attest@v4 + with: + subject-checksums: checksums.txt release-server-redis: strategy: @@ -120,12 +232,12 @@ jobs: # Each of the platforms for which release-artifacts need generated. os: [ ubuntu-22.04, windows-2022, macos-15-large ] runs-on: ${{ matrix.os }} - needs: [ 'release-please' ] + needs: [ 'release-please', 'create-tags' ] if: ${{ needs.release-please.outputs.package-server-redis-released == 'true'}} - outputs: - hashes-linux: ${{ steps.release-server-redis.outputs.hashes-linux }} - hashes-windows: ${{ steps.release-server-redis.outputs.hashes-windows }} - hashes-macos: ${{ steps.release-server-redis.outputs.hashes-macos }} + permissions: + contents: write + attestations: write + id-token: write steps: # https://github.com/actions/checkout/releases/tag/v4.3.0 - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 @@ -138,13 +250,33 @@ jobs: github_token: ${{secrets.GITHUB_TOKEN}} sdk_path: 'libs/server-sdk-redis-source' sdk_cmake_target: 'launchdarkly-cpp-server-redis-source' + - name: Generate checksums file + env: + HASHES_LINUX: ${{ steps.release-server-redis.outputs.hashes-linux }} + HASHES_WINDOWS: ${{ steps.release-server-redis.outputs.hashes-windows }} + HASHES_MACOS: ${{ steps.release-server-redis.outputs.hashes-macos }} + run: | + if [ -n "${HASHES_LINUX}" ]; then + echo "${HASHES_LINUX}" | base64 -d > checksums.txt + elif [ -n "${HASHES_WINDOWS}" ]; then + echo "${HASHES_WINDOWS}" | base64 -d > checksums.txt + elif [ -n "${HASHES_MACOS}" ]; then + echo "${HASHES_MACOS}" | base64 -d > checksums.txt + fi + shell: bash + - name: Attest build provenance + uses: actions/attest@v4 + with: + subject-checksums: checksums.txt release-server-redis-mac-arm64: runs-on: macos-15 - needs: [ 'release-please' ] + needs: [ 'release-please', 'create-tags' ] if: ${{ needs.release-please.outputs.package-server-redis-released == 'true'}} - outputs: - hashes-macos-arm64: ${{ steps.release-server-redis.outputs.hashes-macos }} + permissions: + contents: write + attestations: write + id-token: write steps: # https://github.com/actions/checkout/releases/tag/v4.3.0 - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 @@ -157,93 +289,61 @@ jobs: sdk_path: 'libs/server-sdk-redis-source' sdk_cmake_target: 'launchdarkly-cpp-server-redis-source' mac_artifact_arch: 'arm64' + - name: Generate checksums file + env: + HASHES: ${{ steps.release-server-redis.outputs.hashes-macos }} + run: | + echo "${HASHES}" | base64 -d > checksums.txt + shell: bash + - name: Attest build provenance + uses: actions/attest@v4 + with: + subject-checksums: checksums.txt - release-client-provenance: - needs: [ 'release-please', 'release-client' ] - strategy: - matrix: - # Generates a combined attestation for each platform - os: [ linux, windows, macos ] - permissions: - actions: read - id-token: write - contents: write - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 - with: - base64-subjects: "${{ needs.release-client.outputs[format('hashes-{0}', matrix.os)] }}" - upload-assets: true - upload-tag-name: ${{ needs.release-please.outputs.package-client-tag }} - provenance-name: ${{ format('{0}-client-multiple-provenance.intoto.jsonl', matrix.os) }} - - release-client-mac-arm64-provenance: - needs: [ 'release-please', 'release-client-mac-arm64' ] - permissions: - actions: read - id-token: write - contents: write - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 - with: - base64-subjects: "${{ needs.release-client-mac-arm64.outputs.hashes-macos-arm64 }}" - upload-assets: true - upload-tag-name: ${{ needs.release-please.outputs.package-client-tag }} - provenance-name: 'macos-arm64-client-multiple-provenance.intoto.jsonl' - - release-server-provenance: - needs: [ 'release-please', 'release-server' ] - strategy: - matrix: - # Generates a combined attestation for each platform - os: [ linux, windows, macos ] - permissions: - actions: read - id-token: write - contents: write - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 - with: - base64-subjects: "${{ needs.release-server.outputs[format('hashes-{0}', matrix.os)] }}" - upload-assets: true - upload-tag-name: ${{ needs.release-please.outputs.package-server-tag }} - provenance-name: ${{ format('{0}-server-multiple-provenance.intoto.jsonl', matrix.os) }} - - release-server-mac-arm64-provenance: - needs: [ 'release-please', 'release-server-mac-arm64' ] + publish-release-client: + needs: ['release-please', 'release-client', 'release-client-mac-arm64'] + if: ${{ needs.release-please.outputs.package-client-released == 'true' }} + runs-on: ubuntu-latest permissions: - actions: read - id-token: write contents: write - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 - with: - base64-subjects: "${{ needs.release-server-mac-arm64.outputs.hashes-macos-arm64 }}" - upload-assets: true - upload-tag-name: ${{ needs.release-please.outputs.package-server-tag }} - provenance-name: 'macos-arm64-server-multiple-provenance.intoto.jsonl' + steps: + - name: Publish release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ needs.release-please.outputs.package-client-tag }} + run: > + gh release edit "$TAG_NAME" + --repo ${{ github.repository }} + --draft=false - release-server-redis-provenance: - needs: [ 'release-please', 'release-server-redis' ] - strategy: - matrix: - # Generates a combined attestation for each platform - os: [ linux, windows, macos ] + publish-release-server: + needs: ['release-please', 'release-server', 'release-server-mac-arm64'] + if: ${{ needs.release-please.outputs.package-server-released == 'true' }} + runs-on: ubuntu-latest permissions: - actions: read - id-token: write contents: write - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 - with: - base64-subjects: "${{ needs.release-server-redis.outputs[format('hashes-{0}', matrix.os)] }}" - upload-assets: true - upload-tag-name: ${{ needs.release-please.outputs.package-server-redis-tag }} - provenance-name: ${{ format('{0}-server-redis-multiple-provenance.intoto.jsonl', matrix.os) }} + steps: + - name: Publish release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ needs.release-please.outputs.package-server-tag }} + run: > + gh release edit "$TAG_NAME" + --repo ${{ github.repository }} + --draft=false - release-server-redis-mac-arm64-provenance: - needs: [ 'release-please', 'release-server-redis-mac-arm64' ] + publish-release-server-redis: + needs: ['release-please', 'release-server-redis', 'release-server-redis-mac-arm64'] + if: ${{ needs.release-please.outputs.package-server-redis-released == 'true' }} + runs-on: ubuntu-latest permissions: - actions: read - id-token: write contents: write - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 - with: - base64-subjects: "${{ needs.release-server-redis-mac-arm64.outputs.hashes-macos-arm64 }}" - upload-assets: true - upload-tag-name: ${{ needs.release-please.outputs.package-server-redis-tag }} - provenance-name: 'macos-arm64-server-redis-multiple-provenance.intoto.jsonl' + steps: + - name: Publish release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ needs.release-please.outputs.package-server-redis-tag }} + run: > + gh release edit "$TAG_NAME" + --repo ${{ github.repository }} + --draft=false diff --git a/release-please-config.json b/release-please-config.json index 224c1644a..e76bbb8f6 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -2,6 +2,7 @@ "plugins": [ "node-workspace" ], + "draft": true, "packages": { "libs/client-sdk": { "extra-files": [ From 87b0e9dae6d72cf41a7dc0ad9a3ef69c4931a0f6 Mon Sep 17 00:00:00 2001 From: "mkeeler@launchdarkly.com" Date: Tue, 31 Mar 2026 21:42:45 +0000 Subject: [PATCH 02/12] ci: add force-tag-creation and publish_release option --- .../manual-sdk-release-artifacts.yml | 22 ++++++++++++++- release-please-config.json | 28 +++++++++++++------ 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/.github/workflows/manual-sdk-release-artifacts.yml b/.github/workflows/manual-sdk-release-artifacts.yml index 7ca28cb80..9b30cc3b3 100644 --- a/.github/workflows/manual-sdk-release-artifacts.yml +++ b/.github/workflows/manual-sdk-release-artifacts.yml @@ -16,6 +16,11 @@ on: - libs/client-sdk:launchdarkly-cpp-client - libs/server-sdk:launchdarkly-cpp-server - libs/server-sdk-redis-source:launchdarkly-cpp-server-redis-source + publish_release: + description: 'Publish (un-draft) the release after all artifacts are uploaded?' + type: boolean + required: false + default: true name: Publish SDK Artifacts @@ -76,7 +81,6 @@ jobs: uses: actions/attest@v4 with: subject-checksums: checksums.txt - release-sdk-mac-arm64: needs: split-input runs-on: macos-15 @@ -108,3 +112,19 @@ jobs: uses: actions/attest@v4 with: subject-checksums: checksums.txt + + publish-release: + needs: ['release-sdk', 'release-sdk-mac-arm64'] + if: ${{ inputs.publish_release }} + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Publish release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ inputs.tag }} + run: > + gh release edit "$TAG_NAME" + --repo ${{ github.repository }} + --draft=false diff --git a/release-please-config.json b/release-please-config.json index e76bbb8f6..0693cb538 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -10,7 +10,8 @@ "tests/client_c_bindings_test.cpp", "tests/client_test.cpp", "CMakeLists.txt" - ] + ], + "force-tag-creation": true }, "libs/server-sdk": { "extra-files": [ @@ -18,22 +19,33 @@ "tests/server_c_bindings_test.cpp", "tests/client_test.cpp", "CMakeLists.txt" - ] + ], + "force-tag-creation": true }, "libs/server-sdk-redis-source": { "extra-files": [ "CMakeLists.txt" - ] + ], + "force-tag-creation": true }, "libs/server-sdk-otel": { "bump-minor-pre-major": true, "extra-files": [ "CMakeLists.txt" - ] + ], + "force-tag-creation": true }, - "libs/server-sent-events": {}, - "libs/common": {}, - "libs/internal": {}, - "libs/networking": {} + "libs/server-sent-events": { + "force-tag-creation": true + }, + "libs/common": { + "force-tag-creation": true + }, + "libs/internal": { + "force-tag-creation": true + }, + "libs/networking": { + "force-tag-creation": true + } } } From 54a703dea74e642901d7769186592721ea641c44 Mon Sep 17 00:00:00 2001 From: "mkeeler@launchdarkly.com" Date: Wed, 1 Apr 2026 23:05:43 +0000 Subject: [PATCH 03/12] ci: split release-please into independent release and PR creation steps --- .github/workflows/release-please.yml | 69 ++++++++++++++++------------ 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 5000c6d2e..2572510b3 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -20,38 +20,38 @@ jobs: package-server-otel-released: ${{ steps.release.outputs['libs/server-sdk-otel--release_created'] }} package-server-otel-tag: ${{ steps.release.outputs['libs/server-sdk-otel--tag_name'] }} steps: - # https://github.com/googleapis/release-please-action/releases/tag/v4.3.0 - - uses: googleapis/release-please-action@c2a5a2bd6a758a0937f1ddb1e8950609867ed15c + # Create any releases first, then create tags, and then optionally create any new PRs. + - uses: googleapis/release-please-action@16a9c90856f42705d54a6fda1823352bdc62cf38 # v4.4.0 id: release with: token: ${{ secrets.GITHUB_TOKEN }} + skip-github-pull-request: true - create-tags: - needs: ['release-please'] - if: >- - needs.release-please.outputs.package-client-released == 'true' || - needs.release-please.outputs.package-server-released == 'true' || - needs.release-please.outputs.package-server-redis-released == 'true' || - needs.release-please.outputs.package-server-otel-released == 'true' - runs-on: ubuntu-22.04 - permissions: - contents: write - steps: + # Need the repository content to be able to create and push tags. # https://github.com/actions/checkout/releases/tag/v4.3.0 - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 - with: - fetch-depth: 0 + if: >- + steps.release.outputs['libs/client-sdk--release_created'] == 'true' || + steps.release.outputs['libs/server-sdk--release_created'] == 'true' || + steps.release.outputs['libs/server-sdk-redis-source--release_created'] == 'true' || + steps.release.outputs['libs/server-sdk-otel--release_created'] == 'true' + - name: Create release tags + if: >- + steps.release.outputs['libs/client-sdk--release_created'] == 'true' || + steps.release.outputs['libs/server-sdk--release_created'] == 'true' || + steps.release.outputs['libs/server-sdk-redis-source--release_created'] == 'true' || + steps.release.outputs['libs/server-sdk-otel--release_created'] == 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CLIENT_TAG: ${{ needs.release-please.outputs.package-client-tag }} - SERVER_TAG: ${{ needs.release-please.outputs.package-server-tag }} - SERVER_REDIS_TAG: ${{ needs.release-please.outputs.package-server-redis-tag }} - SERVER_OTEL_TAG: ${{ needs.release-please.outputs.package-server-otel-tag }} - CLIENT_RELEASED: ${{ needs.release-please.outputs.package-client-released }} - SERVER_RELEASED: ${{ needs.release-please.outputs.package-server-released }} - SERVER_REDIS_RELEASED: ${{ needs.release-please.outputs.package-server-redis-released }} - SERVER_OTEL_RELEASED: ${{ needs.release-please.outputs.package-server-otel-released }} + CLIENT_TAG: ${{ steps.release.outputs['libs/client-sdk--tag_name'] }} + SERVER_TAG: ${{ steps.release.outputs['libs/server-sdk--tag_name'] }} + SERVER_REDIS_TAG: ${{ steps.release.outputs['libs/server-sdk-redis-source--tag_name'] }} + SERVER_OTEL_TAG: ${{ steps.release.outputs['libs/server-sdk-otel--tag_name'] }} + CLIENT_RELEASED: ${{ steps.release.outputs['libs/client-sdk--release_created'] }} + SERVER_RELEASED: ${{ steps.release.outputs['libs/server-sdk--release_created'] }} + SERVER_REDIS_RELEASED: ${{ steps.release.outputs['libs/server-sdk-redis-source--release_created'] }} + SERVER_OTEL_RELEASED: ${{ steps.release.outputs['libs/server-sdk-otel--release_created'] }} run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" @@ -78,13 +78,24 @@ jobs: fi done + - uses: googleapis/release-please-action@16a9c90856f42705d54a6fda1823352bdc62cf38 # v4.4.0 + if: >- + steps.release.outputs['libs/client-sdk--release_created'] != 'true' && + steps.release.outputs['libs/server-sdk--release_created'] != 'true' && + steps.release.outputs['libs/server-sdk-redis-source--release_created'] != 'true' && + steps.release.outputs['libs/server-sdk-otel--release_created'] != 'true' + id: release-prs + with: + token: ${{ secrets.GITHUB_TOKEN }} + skip-github-release: true + release-client: strategy: matrix: # Each of the platforms for which release-artifacts need generated. os: [ ubuntu-22.04, windows-2022, macos-15-large ] runs-on: ${{ matrix.os }} - needs: [ 'release-please', 'create-tags' ] + needs: [ 'release-please' ] if: ${{ needs.release-please.outputs.package-client-released == 'true'}} permissions: contents: write @@ -123,7 +134,7 @@ jobs: release-client-mac-arm64: runs-on: macos-15 - needs: [ 'release-please', 'create-tags' ] + needs: [ 'release-please' ] if: ${{ needs.release-please.outputs.package-client-released == 'true'}} permissions: contents: write @@ -158,7 +169,7 @@ jobs: # Each of the platforms for which release-artifacts need generated. os: [ ubuntu-22.04, windows-2022, macos-15-large ] runs-on: ${{ matrix.os }} - needs: [ 'release-please', 'create-tags' ] + needs: [ 'release-please' ] if: ${{ needs.release-please.outputs.package-server-released == 'true'}} permissions: contents: write @@ -197,7 +208,7 @@ jobs: release-server-mac-arm64: runs-on: macos-15 - needs: [ 'release-please', 'create-tags' ] + needs: [ 'release-please' ] if: ${{ needs.release-please.outputs.package-server-released == 'true'}} permissions: contents: write @@ -232,7 +243,7 @@ jobs: # Each of the platforms for which release-artifacts need generated. os: [ ubuntu-22.04, windows-2022, macos-15-large ] runs-on: ${{ matrix.os }} - needs: [ 'release-please', 'create-tags' ] + needs: [ 'release-please' ] if: ${{ needs.release-please.outputs.package-server-redis-released == 'true'}} permissions: contents: write @@ -271,7 +282,7 @@ jobs: release-server-redis-mac-arm64: runs-on: macos-15 - needs: [ 'release-please', 'create-tags' ] + needs: [ 'release-please' ] if: ${{ needs.release-please.outputs.package-server-redis-released == 'true'}} permissions: contents: write From 9b6cfae68f189d7aff7f7c730e1eb729163b4fdd Mon Sep 17 00:00:00 2001 From: "mkeeler@launchdarkly.com" Date: Thu, 2 Apr 2026 16:42:50 +0000 Subject: [PATCH 04/12] ci: fix publish_release boolean/string condition using format() --- .github/workflows/manual-sdk-release-artifacts.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/manual-sdk-release-artifacts.yml b/.github/workflows/manual-sdk-release-artifacts.yml index 9b30cc3b3..99e14fd67 100644 --- a/.github/workflows/manual-sdk-release-artifacts.yml +++ b/.github/workflows/manual-sdk-release-artifacts.yml @@ -115,7 +115,7 @@ jobs: publish-release: needs: ['release-sdk', 'release-sdk-mac-arm64'] - if: ${{ inputs.publish_release }} + if: ${{ format('{0}', inputs.publish_release) == 'true' }} runs-on: ubuntu-latest permissions: contents: write From 2e858503661361877e7f85428cd1e553d1cec981 Mon Sep 17 00:00:00 2001 From: "mkeeler@launchdarkly.com" Date: Thu, 2 Apr 2026 22:05:04 +0000 Subject: [PATCH 05/12] ci: fix base64 decode for macOS BSD compatibility (-D instead of -d) --- .../manual-sdk-release-artifacts.yml | 11 ++++--- .github/workflows/release-please.yml | 33 ++++++++++++------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/.github/workflows/manual-sdk-release-artifacts.yml b/.github/workflows/manual-sdk-release-artifacts.yml index 99e14fd67..77bb7dae6 100644 --- a/.github/workflows/manual-sdk-release-artifacts.yml +++ b/.github/workflows/manual-sdk-release-artifacts.yml @@ -69,12 +69,14 @@ jobs: HASHES_WINDOWS: ${{ steps.release-sdk.outputs.hashes-windows }} HASHES_MACOS: ${{ steps.release-sdk.outputs.hashes-macos }} run: | + # BSD base64 (macOS) uses -D to decode; GNU base64 (Linux/Windows) uses -d. + if [[ "$OSTYPE" == darwin* ]]; then B64_DECODE="base64 -D"; else B64_DECODE="base64 -d"; fi if [ -n "${HASHES_LINUX}" ]; then - echo "${HASHES_LINUX}" | base64 -d > checksums.txt + echo "${HASHES_LINUX}" | $B64_DECODE > checksums.txt elif [ -n "${HASHES_WINDOWS}" ]; then - echo "${HASHES_WINDOWS}" | base64 -d > checksums.txt + echo "${HASHES_WINDOWS}" | $B64_DECODE > checksums.txt elif [ -n "${HASHES_MACOS}" ]; then - echo "${HASHES_MACOS}" | base64 -d > checksums.txt + echo "${HASHES_MACOS}" | $B64_DECODE > checksums.txt fi shell: bash - name: Attest build provenance @@ -106,7 +108,8 @@ jobs: env: HASHES: ${{ steps.release-sdk.outputs.hashes-macos }} run: | - echo "${HASHES}" | base64 -d > checksums.txt + # This job always runs on macOS, so use -D (BSD base64 decode). + echo "${HASHES}" | base64 -D > checksums.txt shell: bash - name: Attest build provenance uses: actions/attest@v4 diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 2572510b3..23083d608 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -119,12 +119,14 @@ jobs: HASHES_WINDOWS: ${{ steps.release-client.outputs.hashes-windows }} HASHES_MACOS: ${{ steps.release-client.outputs.hashes-macos }} run: | + # BSD base64 (macOS) uses -D to decode; GNU base64 (Linux/Windows) uses -d. + if [[ "$OSTYPE" == darwin* ]]; then B64_DECODE="base64 -D"; else B64_DECODE="base64 -d"; fi if [ -n "${HASHES_LINUX}" ]; then - echo "${HASHES_LINUX}" | base64 -d > checksums.txt + echo "${HASHES_LINUX}" | $B64_DECODE > checksums.txt elif [ -n "${HASHES_WINDOWS}" ]; then - echo "${HASHES_WINDOWS}" | base64 -d > checksums.txt + echo "${HASHES_WINDOWS}" | $B64_DECODE > checksums.txt elif [ -n "${HASHES_MACOS}" ]; then - echo "${HASHES_MACOS}" | base64 -d > checksums.txt + echo "${HASHES_MACOS}" | $B64_DECODE > checksums.txt fi shell: bash - name: Attest build provenance @@ -156,7 +158,8 @@ jobs: env: HASHES: ${{ steps.release-client.outputs.hashes-macos }} run: | - echo "${HASHES}" | base64 -d > checksums.txt + # This job always runs on macOS, so use -D (BSD base64 decode). + echo "${HASHES}" | base64 -D > checksums.txt shell: bash - name: Attest build provenance uses: actions/attest@v4 @@ -193,12 +196,14 @@ jobs: HASHES_WINDOWS: ${{ steps.release-server.outputs.hashes-windows }} HASHES_MACOS: ${{ steps.release-server.outputs.hashes-macos }} run: | + # BSD base64 (macOS) uses -D to decode; GNU base64 (Linux/Windows) uses -d. + if [[ "$OSTYPE" == darwin* ]]; then B64_DECODE="base64 -D"; else B64_DECODE="base64 -d"; fi if [ -n "${HASHES_LINUX}" ]; then - echo "${HASHES_LINUX}" | base64 -d > checksums.txt + echo "${HASHES_LINUX}" | $B64_DECODE > checksums.txt elif [ -n "${HASHES_WINDOWS}" ]; then - echo "${HASHES_WINDOWS}" | base64 -d > checksums.txt + echo "${HASHES_WINDOWS}" | $B64_DECODE > checksums.txt elif [ -n "${HASHES_MACOS}" ]; then - echo "${HASHES_MACOS}" | base64 -d > checksums.txt + echo "${HASHES_MACOS}" | $B64_DECODE > checksums.txt fi shell: bash - name: Attest build provenance @@ -230,7 +235,8 @@ jobs: env: HASHES: ${{ steps.release-server.outputs.hashes-macos }} run: | - echo "${HASHES}" | base64 -d > checksums.txt + # This job always runs on macOS, so use -D (BSD base64 decode). + echo "${HASHES}" | base64 -D > checksums.txt shell: bash - name: Attest build provenance uses: actions/attest@v4 @@ -267,12 +273,14 @@ jobs: HASHES_WINDOWS: ${{ steps.release-server-redis.outputs.hashes-windows }} HASHES_MACOS: ${{ steps.release-server-redis.outputs.hashes-macos }} run: | + # BSD base64 (macOS) uses -D to decode; GNU base64 (Linux/Windows) uses -d. + if [[ "$OSTYPE" == darwin* ]]; then B64_DECODE="base64 -D"; else B64_DECODE="base64 -d"; fi if [ -n "${HASHES_LINUX}" ]; then - echo "${HASHES_LINUX}" | base64 -d > checksums.txt + echo "${HASHES_LINUX}" | $B64_DECODE > checksums.txt elif [ -n "${HASHES_WINDOWS}" ]; then - echo "${HASHES_WINDOWS}" | base64 -d > checksums.txt + echo "${HASHES_WINDOWS}" | $B64_DECODE > checksums.txt elif [ -n "${HASHES_MACOS}" ]; then - echo "${HASHES_MACOS}" | base64 -d > checksums.txt + echo "${HASHES_MACOS}" | $B64_DECODE > checksums.txt fi shell: bash - name: Attest build provenance @@ -304,7 +312,8 @@ jobs: env: HASHES: ${{ steps.release-server-redis.outputs.hashes-macos }} run: | - echo "${HASHES}" | base64 -d > checksums.txt + # This job always runs on macOS, so use -D (BSD base64 decode). + echo "${HASHES}" | base64 -D > checksums.txt shell: bash - name: Attest build provenance uses: actions/attest@v4 From d509dbb08e7451fcc2c1ab290017dadf91201509 Mon Sep 17 00:00:00 2001 From: "mkeeler@launchdarkly.com" Date: Mon, 6 Apr 2026 19:46:44 +0000 Subject: [PATCH 06/12] ci: add missing publish-release-server-otel job to un-draft server-otel releases --- .github/workflows/release-please.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 23083d608..3d3df5be0 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -367,3 +367,19 @@ jobs: gh release edit "$TAG_NAME" --repo ${{ github.repository }} --draft=false + + publish-release-server-otel: + needs: ['release-please'] + if: ${{ needs.release-please.outputs.package-server-otel-released == 'true' }} + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Publish release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ needs.release-please.outputs.package-server-otel-tag }} + run: > + gh release edit "$TAG_NAME" + --repo ${{ github.repository }} + --draft=false From 0cb273caa5ba0e6fad601707959f8900662b7c58 Mon Sep 17 00:00:00 2001 From: Ryan Lamb <4955475+kinyoklion@users.noreply.github.com> Date: Tue, 16 Jun 2026 09:57:02 -0700 Subject: [PATCH 07/12] ci: scope draft releases to packages with publish-release jobs --- release-please-config.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/release-please-config.json b/release-please-config.json index 02581a6eb..4f9626e07 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -2,7 +2,6 @@ "plugins": [ "node-workspace" ], - "draft": true, "packages": { "libs/client-sdk": { "component": "launchdarkly-cpp-client", @@ -12,6 +11,7 @@ "tests/client_test.cpp", "CMakeLists.txt" ], + "draft": true, "force-tag-creation": true }, "libs/server-sdk": { @@ -22,6 +22,7 @@ "tests/client_test.cpp", "CMakeLists.txt" ], + "draft": true, "force-tag-creation": true }, "libs/server-sdk-redis-source": { @@ -29,6 +30,7 @@ "extra-files": [ "CMakeLists.txt" ], + "draft": true, "force-tag-creation": true }, "libs/server-sdk-dynamodb-source": { @@ -45,6 +47,7 @@ "extra-files": [ "CMakeLists.txt" ], + "draft": true, "force-tag-creation": true }, "libs/server-sent-events": { From 1b4bb015d44d432659efd0cf7b9c40c0c3677efb Mon Sep 17 00:00:00 2001 From: Ryan Lamb <4955475+kinyoklion@users.noreply.github.com> Date: Tue, 16 Jun 2026 09:57:06 -0700 Subject: [PATCH 08/12] ci: collapse release-please into a single call, removing inline tag step --- .github/workflows/release-please.yml | 86 +++++----------------------- 1 file changed, 15 insertions(+), 71 deletions(-) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index be2ee9434..e58e9bd7d 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -20,76 +20,14 @@ jobs: package-server-otel-released: ${{ steps.release.outputs['libs/server-sdk-otel--release_created'] }} package-server-otel-tag: ${{ steps.release.outputs['libs/server-sdk-otel--tag_name'] }} steps: - # Create any releases first, then create tags, and then optionally create any new PRs. + # release-please-action v5+ (release-please >= 17) honors `force-tag-creation` + # for draft releases by creating the tag ref via the GitHub API before the + # release object, so a single invocation handles both releases and PRs. # https://github.com/googleapis/release-please-action/releases/tag/v5.0.0 - uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0 id: release with: token: ${{ secrets.GITHUB_TOKEN }} - skip-github-pull-request: true - - # Need the repository content to be able to create and push tags. - # https://github.com/actions/checkout/releases/tag/v4.3.0 - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 - if: >- - steps.release.outputs['libs/client-sdk--release_created'] == 'true' || - steps.release.outputs['libs/server-sdk--release_created'] == 'true' || - steps.release.outputs['libs/server-sdk-redis-source--release_created'] == 'true' || - steps.release.outputs['libs/server-sdk-otel--release_created'] == 'true' - - - name: Create release tags - if: >- - steps.release.outputs['libs/client-sdk--release_created'] == 'true' || - steps.release.outputs['libs/server-sdk--release_created'] == 'true' || - steps.release.outputs['libs/server-sdk-redis-source--release_created'] == 'true' || - steps.release.outputs['libs/server-sdk-otel--release_created'] == 'true' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CLIENT_TAG: ${{ steps.release.outputs['libs/client-sdk--tag_name'] }} - SERVER_TAG: ${{ steps.release.outputs['libs/server-sdk--tag_name'] }} - SERVER_REDIS_TAG: ${{ steps.release.outputs['libs/server-sdk-redis-source--tag_name'] }} - SERVER_OTEL_TAG: ${{ steps.release.outputs['libs/server-sdk-otel--tag_name'] }} - CLIENT_RELEASED: ${{ steps.release.outputs['libs/client-sdk--release_created'] }} - SERVER_RELEASED: ${{ steps.release.outputs['libs/server-sdk--release_created'] }} - SERVER_REDIS_RELEASED: ${{ steps.release.outputs['libs/server-sdk-redis-source--release_created'] }} - SERVER_OTEL_RELEASED: ${{ steps.release.outputs['libs/server-sdk-otel--release_created'] }} - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - for pair in \ - "${CLIENT_RELEASED}:${CLIENT_TAG}" \ - "${SERVER_RELEASED}:${SERVER_TAG}" \ - "${SERVER_REDIS_RELEASED}:${SERVER_REDIS_TAG}" \ - "${SERVER_OTEL_RELEASED}:${SERVER_OTEL_TAG}"; do - - RELEASED="${pair%%:*}" - TAG="${pair#*:}" - - if [ "${RELEASED}" != "true" ] || [ -z "${TAG}" ]; then - continue - fi - - if gh api "repos/${{ github.repository }}/git/ref/tags/${TAG}" >/dev/null 2>&1; then - echo "Tag ${TAG} already exists, skipping creation." - else - echo "Creating tag ${TAG}." - git tag "${TAG}" - git push origin "${TAG}" - fi - done - - # https://github.com/googleapis/release-please-action/releases/tag/v5.0.0 - - uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0 - if: >- - steps.release.outputs['libs/client-sdk--release_created'] != 'true' && - steps.release.outputs['libs/server-sdk--release_created'] != 'true' && - steps.release.outputs['libs/server-sdk-redis-source--release_created'] != 'true' && - steps.release.outputs['libs/server-sdk-otel--release_created'] != 'true' - id: release-prs - with: - token: ${{ secrets.GITHUB_TOKEN }} - skip-github-release: true release-client: strategy: @@ -131,8 +69,9 @@ jobs: echo "${HASHES_MACOS}" | $B64_DECODE > checksums.txt fi shell: bash + # https://github.com/actions/attest/releases/tag/v4.1.0 - name: Attest build provenance - uses: actions/attest@v4 + uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 with: subject-checksums: checksums.txt @@ -163,8 +102,9 @@ jobs: # This job always runs on macOS, so use -D (BSD base64 decode). echo "${HASHES}" | base64 -D > checksums.txt shell: bash + # https://github.com/actions/attest/releases/tag/v4.1.0 - name: Attest build provenance - uses: actions/attest@v4 + uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 with: subject-checksums: checksums.txt @@ -208,8 +148,9 @@ jobs: echo "${HASHES_MACOS}" | $B64_DECODE > checksums.txt fi shell: bash + # https://github.com/actions/attest/releases/tag/v4.1.0 - name: Attest build provenance - uses: actions/attest@v4 + uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 with: subject-checksums: checksums.txt @@ -240,8 +181,9 @@ jobs: # This job always runs on macOS, so use -D (BSD base64 decode). echo "${HASHES}" | base64 -D > checksums.txt shell: bash + # https://github.com/actions/attest/releases/tag/v4.1.0 - name: Attest build provenance - uses: actions/attest@v4 + uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 with: subject-checksums: checksums.txt @@ -285,8 +227,9 @@ jobs: echo "${HASHES_MACOS}" | $B64_DECODE > checksums.txt fi shell: bash + # https://github.com/actions/attest/releases/tag/v4.1.0 - name: Attest build provenance - uses: actions/attest@v4 + uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 with: subject-checksums: checksums.txt @@ -317,8 +260,9 @@ jobs: # This job always runs on macOS, so use -D (BSD base64 decode). echo "${HASHES}" | base64 -D > checksums.txt shell: bash + # https://github.com/actions/attest/releases/tag/v4.1.0 - name: Attest build provenance - uses: actions/attest@v4 + uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 with: subject-checksums: checksums.txt From 247deb441ff4d16fee43dda2977d2832b982baad Mon Sep 17 00:00:00 2001 From: Ryan Lamb <4955475+kinyoklion@users.noreply.github.com> Date: Tue, 16 Jun 2026 09:57:07 -0700 Subject: [PATCH 09/12] ci: pin actions/attest to v4.1.0 by SHA --- .github/workflows/manual-sdk-release-artifacts.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/manual-sdk-release-artifacts.yml b/.github/workflows/manual-sdk-release-artifacts.yml index 7c095b8dc..865bafba5 100644 --- a/.github/workflows/manual-sdk-release-artifacts.yml +++ b/.github/workflows/manual-sdk-release-artifacts.yml @@ -80,8 +80,9 @@ jobs: echo "${HASHES_MACOS}" | $B64_DECODE > checksums.txt fi shell: bash + # https://github.com/actions/attest/releases/tag/v4.1.0 - name: Attest build provenance - uses: actions/attest@v4 + uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 with: subject-checksums: checksums.txt release-sdk-mac-arm64: @@ -112,8 +113,9 @@ jobs: # This job always runs on macOS, so use -D (BSD base64 decode). echo "${HASHES}" | base64 -D > checksums.txt shell: bash + # https://github.com/actions/attest/releases/tag/v4.1.0 - name: Attest build provenance - uses: actions/attest@v4 + uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 with: subject-checksums: checksums.txt From 79db44bc45f32ef6140c6b85c34e358586d74580 Mon Sep 17 00:00:00 2001 From: Bee Klimt Date: Mon, 29 Jun 2026 09:58:42 -0700 Subject: [PATCH 10/12] ci: Add draft release for dynamodb-source --- release-please-config.json | 1 + 1 file changed, 1 insertion(+) diff --git a/release-please-config.json b/release-please-config.json index 4f9626e07..efad6b48d 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -39,6 +39,7 @@ "extra-files": [ "CMakeLists.txt" ], + "draft": true, "force-tag-creation": true }, "libs/server-sdk-otel": { From b4376776e38efb19b12a380939f491edcb7fa84e Mon Sep 17 00:00:00 2001 From: Bee Klimt Date: Mon, 29 Jun 2026 10:19:13 -0700 Subject: [PATCH 11/12] Revert "ci: Add draft release for dynamodb-source" This reverts commit 79db44bc45f32ef6140c6b85c34e358586d74580. --- release-please-config.json | 1 - 1 file changed, 1 deletion(-) diff --git a/release-please-config.json b/release-please-config.json index efad6b48d..4f9626e07 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -39,7 +39,6 @@ "extra-files": [ "CMakeLists.txt" ], - "draft": true, "force-tag-creation": true }, "libs/server-sdk-otel": { From 722ee5360781b94c4986459e59877ab1352bc24b Mon Sep 17 00:00:00 2001 From: Bee Klimt Date: Mon, 29 Jun 2026 14:26:05 -0700 Subject: [PATCH 12/12] ci: Enable dynamodb-source releases via release-please (#568) ## Summary Wires `libs/server-sdk-dynamodb-source` into the release-please draft + publish flow so its releases cut and un-draft automatically, same as client/server/redis. - `"draft": true` in `release-please-config.json` for dynamodb. - `release-server-dynamodb` (matrix) + `-mac-arm64` + `publish-release-server-dynamodb` jobs in `release-please.yml`. Mirrors the redis pattern. - `sdk-release` action passes `CURL_ROOT` and `CMAKE_PREFIX_PATH` to its Linux and macOS Boost.Beast build steps. aws-sdk-cpp calls `find_package(CURL)` on Linux/macOS regardless of `LD_CURL_NETWORKING`; on macOS the hint is needed because homebrew's curl isn't in cmake's default search path. Windows uses WinHTTP, so aws-sdk-cpp doesn't need libcurl there and the env isn't passed. The dynamodb release path has never been cut end-to-end. Per-package CI builds dynamodb daily, but the `sdk-release` composite action hasn't been run against it -- the first real release may surface latent issues. --- .github/actions/sdk-release/action.yml | 6 ++ .github/workflows/release-please.yml | 97 ++++++++++++++++++++++++++ release-please-config.json | 1 + 3 files changed, 104 insertions(+) diff --git a/.github/actions/sdk-release/action.yml b/.github/actions/sdk-release/action.yml index 6a1541ad5..6da28158b 100644 --- a/.github/actions/sdk-release/action.yml +++ b/.github/actions/sdk-release/action.yml @@ -59,6 +59,9 @@ runs: WORKSPACE: ${{ inputs.sdk_path }} BOOST_ROOT: ${{ steps.install-boost.outputs.BOOST_ROOT }} OPENSSL_ROOT_DIR: ${{ steps.install-openssl.outputs.OPENSSL_ROOT_DIR }} + # aws-sdk-cpp (dynamodb-source) calls find_package(CURL) on Linux/macOS, regardless of LD_CURL_NETWORKING. + CURL_ROOT: ${{ steps.install-curl.outputs.CURL_ROOT }} + CMAKE_PREFIX_PATH: ${{ steps.install-curl.outputs.CURL_ROOT }} - name: Build Linux Artifacts (CURL) if: runner.os == 'Linux' @@ -253,6 +256,9 @@ runs: WORKSPACE: ${{ inputs.sdk_path }} BOOST_ROOT: ${{ steps.install-boost.outputs.BOOST_ROOT }} OPENSSL_ROOT_DIR: ${{ steps.install-openssl.outputs.OPENSSL_ROOT_DIR }} + # aws-sdk-cpp (dynamodb-source) calls find_package(CURL) on Linux/macOS, regardless of LD_CURL_NETWORKING. + CURL_ROOT: ${{ steps.install-curl.outputs.CURL_ROOT }} + CMAKE_PREFIX_PATH: ${{ steps.install-curl.outputs.CURL_ROOT }} - name: Build Mac Artifacts (CURL) if: runner.os == 'macOS' diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index e58e9bd7d..909694a04 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -17,6 +17,8 @@ jobs: package-server-tag: ${{ steps.release.outputs['libs/server-sdk--tag_name'] }} package-server-redis-released: ${{ steps.release.outputs['libs/server-sdk-redis-source--release_created'] }} package-server-redis-tag: ${{ steps.release.outputs['libs/server-sdk-redis-source--tag_name'] }} + package-server-dynamodb-released: ${{ steps.release.outputs['libs/server-sdk-dynamodb-source--release_created'] }} + package-server-dynamodb-tag: ${{ steps.release.outputs['libs/server-sdk-dynamodb-source--tag_name'] }} package-server-otel-released: ${{ steps.release.outputs['libs/server-sdk-otel--release_created'] }} package-server-otel-tag: ${{ steps.release.outputs['libs/server-sdk-otel--tag_name'] }} steps: @@ -266,6 +268,85 @@ jobs: with: subject-checksums: checksums.txt + release-server-dynamodb: + strategy: + matrix: + # Each of the platforms for which release-artifacts need generated. + os: [ ubuntu-22.04, windows-2022, macos-15-large ] + runs-on: ${{ matrix.os }} + needs: [ 'release-please' ] + if: ${{ needs.release-please.outputs.package-server-dynamodb-released == 'true'}} + permissions: + contents: write + attestations: write + id-token: write + steps: + # https://github.com/actions/checkout/releases/tag/v4.3.0 + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 + - id: release-server-dynamodb + name: Full release of libs/server-sdk-dynamodb-source + uses: ./.github/actions/sdk-release + with: + # The tag of the release to upload artifacts to. + tag_name: ${{ needs.release-please.outputs.package-server-dynamodb-tag }} + github_token: ${{secrets.GITHUB_TOKEN}} + sdk_path: 'libs/server-sdk-dynamodb-source' + sdk_cmake_target: 'launchdarkly-cpp-server-dynamodb-source' + - name: Generate checksums file + env: + HASHES_LINUX: ${{ steps.release-server-dynamodb.outputs.hashes-linux }} + HASHES_WINDOWS: ${{ steps.release-server-dynamodb.outputs.hashes-windows }} + HASHES_MACOS: ${{ steps.release-server-dynamodb.outputs.hashes-macos }} + run: | + # BSD base64 (macOS) uses -D to decode; GNU base64 (Linux/Windows) uses -d. + if [[ "$OSTYPE" == darwin* ]]; then B64_DECODE="base64 -D"; else B64_DECODE="base64 -d"; fi + if [ -n "${HASHES_LINUX}" ]; then + echo "${HASHES_LINUX}" | $B64_DECODE > checksums.txt + elif [ -n "${HASHES_WINDOWS}" ]; then + echo "${HASHES_WINDOWS}" | $B64_DECODE > checksums.txt + elif [ -n "${HASHES_MACOS}" ]; then + echo "${HASHES_MACOS}" | $B64_DECODE > checksums.txt + fi + shell: bash + # https://github.com/actions/attest/releases/tag/v4.1.0 + - name: Attest build provenance + uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 + with: + subject-checksums: checksums.txt + + release-server-dynamodb-mac-arm64: + runs-on: macos-15 + needs: [ 'release-please' ] + if: ${{ needs.release-please.outputs.package-server-dynamodb-released == 'true'}} + permissions: + contents: write + attestations: write + id-token: write + steps: + # https://github.com/actions/checkout/releases/tag/v4.3.0 + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 + - id: release-server-dynamodb + name: Full release of libs/server-sdk-dynamodb-source (macOS arm64) + uses: ./.github/actions/sdk-release + with: + tag_name: ${{ needs.release-please.outputs.package-server-dynamodb-tag }} + github_token: ${{secrets.GITHUB_TOKEN}} + sdk_path: 'libs/server-sdk-dynamodb-source' + sdk_cmake_target: 'launchdarkly-cpp-server-dynamodb-source' + mac_artifact_arch: 'arm64' + - name: Generate checksums file + env: + HASHES: ${{ steps.release-server-dynamodb.outputs.hashes-macos }} + run: | + # This job always runs on macOS, so use -D (BSD base64 decode). + echo "${HASHES}" | base64 -D > checksums.txt + shell: bash + # https://github.com/actions/attest/releases/tag/v4.1.0 + - name: Attest build provenance + uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 + with: + subject-checksums: checksums.txt + publish-release-client: needs: ['release-please', 'release-client', 'release-client-mac-arm64'] if: ${{ needs.release-please.outputs.package-client-released == 'true' }} @@ -314,6 +395,22 @@ jobs: --repo ${{ github.repository }} --draft=false + publish-release-server-dynamodb: + needs: ['release-please', 'release-server-dynamodb', 'release-server-dynamodb-mac-arm64'] + if: ${{ needs.release-please.outputs.package-server-dynamodb-released == 'true' }} + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Publish release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ needs.release-please.outputs.package-server-dynamodb-tag }} + run: > + gh release edit "$TAG_NAME" + --repo ${{ github.repository }} + --draft=false + publish-release-server-otel: needs: ['release-please'] if: ${{ needs.release-please.outputs.package-server-otel-released == 'true' }} diff --git a/release-please-config.json b/release-please-config.json index 4f9626e07..efad6b48d 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -39,6 +39,7 @@ "extra-files": [ "CMakeLists.txt" ], + "draft": true, "force-tag-creation": true }, "libs/server-sdk-otel": {