diff --git a/.github/workflows/manual-sdk-release-artifacts.yml b/.github/workflows/manual-sdk-release-artifacts.yml index a265bf2d5..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 @@ -40,10 +45,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 +63,31 @@ 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 +102,29 @@ jobs: sdk_path: ${{ needs.split-input.outputs.sdk_path}} sdk_cmake_target: ${{ needs.split-input.outputs.sdk_cmake_target}} mac_artifact_arch: 'arm64' + - 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 - 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' ] + publish-release: + needs: ['release-sdk', 'release-sdk-mac-arm64'] + if: ${{ inputs.publish_release }} + 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-sdk-mac-arm64.outputs.hashes-macos-arm64 }}" - upload-assets: true - upload-tag-name: ${{ inputs.tag }} - provenance-name: 'macos-arm64-multiple-provenance.intoto.jsonl' + 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/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index f6af1d0bb..2572510b3 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -20,11 +20,74 @@ 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 + + # 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 + + - 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: @@ -34,10 +97,10 @@ jobs: runs-on: ${{ matrix.os }} needs: [ 'release-please' ] 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 +113,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' ] 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 +152,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: @@ -78,10 +171,10 @@ jobs: runs-on: ${{ matrix.os }} needs: [ 'release-please' ] 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 +187,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' ] 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 +226,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: @@ -122,10 +245,10 @@ jobs: runs-on: ${{ matrix.os }} needs: [ 'release-please' ] 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 +261,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' ] 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 +300,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' - - release-server-redis-provenance: - needs: [ 'release-please', 'release-server-redis' ] - strategy: - matrix: - # Generates a combined attestation for each platform - os: [ linux, windows, macos ] + 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 + + 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) }} - - release-server-redis-mac-arm64-provenance: - needs: [ 'release-please', 'release-server-redis-mac-arm64' ] + 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 + + 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..0693cb538 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": [ @@ -9,7 +10,8 @@ "tests/client_c_bindings_test.cpp", "tests/client_test.cpp", "CMakeLists.txt" - ] + ], + "force-tag-creation": true }, "libs/server-sdk": { "extra-files": [ @@ -17,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 + } } }