diff --git a/.github/actions/full-release/action.yml b/.github/actions/full-release/action.yml index a9f9accb..b4197b1b 100644 --- a/.github/actions/full-release/action.yml +++ b/.github/actions/full-release/action.yml @@ -25,6 +25,10 @@ inputs: token: description: 'The GitHub token to use for publishing documentation.' required: true +outputs: + hashes: + description: sha256sum hashes of built artifacts + value: ${{ steps.publish.outputs.hashes }} runs: using: composite @@ -59,6 +63,7 @@ runs: dll_name: ${{ inputs.dll_name }} - name: Publish Nupkg + id: publish uses: ./.github/actions/publish-package with: project_file: ${{ inputs.project_file }} diff --git a/.github/actions/publish-package/action.yml b/.github/actions/publish-package/action.yml index 92ea6b11..ed5a467b 100644 --- a/.github/actions/publish-package/action.yml +++ b/.github/actions/publish-package/action.yml @@ -7,6 +7,10 @@ inputs: dry_run: description: 'Is this a dry run. If so no package will be published.' required: true +outputs: + hashes: + description: sha256sum hashes of built artifacts + value: ${{ steps.hash.outputs.hashes }} runs: using: composite @@ -27,6 +31,13 @@ runs: echo "published ${pkg}" done + - name: Hash nuget packages + id: hash + if: ${{ inputs.dry_run == 'false' }} + shell: bash + run: | + echo "hashes=$(sha256sum ./nupkgs/*.nupkg ./nupkgs/*.snupkg | base64 -w0)" >> "$GITHUB_OUTPUT" + - name: Dry Run Publish if: ${{ inputs.dry_run == 'true' }} shell: bash diff --git a/.github/workflows/manual-publish.yml b/.github/workflows/manual-publish.yml index 1097c47e..c74851e4 100644 --- a/.github/workflows/manual-publish.yml +++ b/.github/workflows/manual-publish.yml @@ -13,6 +13,13 @@ on: description: 'Is this a dry run. If so no package will be published.' type: boolean required: true + generate_provenance: + description: 'Whether or not to generate provenance for this manual publish. Default behavior: generate only on main branch.' + type: choice + options: + - Default + - Generate + - Do not generate jobs: build: @@ -20,9 +27,13 @@ jobs: permissions: id-token: write contents: write + outputs: + server-sdk-hashes: ${{ steps.server-sdk-release.outputs.hashes }} + telemetry-hashes: ${{ steps.telemetry-release.outputs.hashes }} steps: - uses: actions/checkout@v4 - uses: ./.github/actions/full-release + id: server-sdk-release if: ${{ inputs.pkg_name == 'LaunchDarkly.ServerSdk' }} with: workspace_path: 'pkgs/sdk/server' @@ -35,6 +46,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - uses: ./.github/actions/full-release + id: telemetry-release if: ${{ inputs.pkg_name == 'LaunchDarkly.ServerSdk.Telemetry' }} with: workspace_path: 'pkgs/telemetry' @@ -45,3 +57,34 @@ jobs: dry_run: ${{ inputs.dry_run }} aws_role: ${{ vars.AWS_ROLE_ARN }} token: ${{ secrets.GITHUB_TOKEN }} + + release-sdk-server-provenance: + needs: ['build'] + permissions: + actions: read + id-token: write + contents: write + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.10.0 + if: | + (inputs.generate_provenance == 'Generate' || (inputs.generate_provenance == 'Default' && github.ref_name == 'main')) && + inputs.pkg_name == 'LaunchDarkly.ServerSdk' + with: + base64-subjects: "${{ needs.build.outputs.server-sdk-hashes }}" + upload-assets: true + provenance-name: ${{ 'LaunchDarkly.ServerSdk_provenance.intoto.jsonl' }} + + + release-telemetry-server-provenance: + needs: ['build'] + permissions: + actions: read + id-token: write + contents: write + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.10.0 + if: | + (inputs.generate_provenance == 'Generate' || (inputs.generate_provenance == 'Default' && github.ref_name == 'main')) && + inputs.pkg_name == 'LaunchDarkly.ServerSdk.Telemetry' + with: + base64-subjects: "${{ needs.build.outputs.telemetry-hashes }}" + upload-assets: true + provenance-name: ${{ 'LaunchDarkly.ServerSdk.Telemetry_provenance.intoto.jsonl' }} \ No newline at end of file diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 1f00c13a..b92e0a66 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -12,6 +12,7 @@ jobs: outputs: package-sdk-server-released: ${{ steps.release.outputs['pkgs/sdk/server--release_created'] }} package-sdk-server-telemetry-released: ${{ steps.release.outputs['pkgs/telemetry--release_created'] }} + tag_name: ${{ steps.release.outputs.tag_name }} steps: - uses: google-github-actions/release-please-action@v4 @@ -28,9 +29,12 @@ jobs: contents: write pull-requests: write if: ${{ needs.release-please.outputs.package-sdk-server-released == 'true'}} + outputs: + hashes: ${{ steps.full-release.outputs.hashes }} steps: - uses: actions/checkout@v4 - uses: ./.github/actions/full-release + id: full-release with: workspace_path: 'pkgs/sdk/server' project_file: 'pkgs/sdk/server/src/LaunchDarkly.ServerSdk.csproj' @@ -41,6 +45,19 @@ jobs: aws_role: ${{ vars.AWS_ROLE_ARN }} token: ${{ secrets.GITHUB_TOKEN }} + release-sdk-server-provenance: + needs: ['release-please', 'release-sdk-server'] + permissions: + actions: read + id-token: write + contents: write + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.10.0 + with: + base64-subjects: "${{ needs.release-sdk-server.outputs.hashes }}" + upload-assets: true + upload-tag-name: ${{ needs.release-please.outputs.tag_name }} + provenance-name: ${{ format('LaunchDarkly.ServerSdk-{0}_provenance.intoto.jsonl', needs.release-please.outputs.tag_name) }} + release-telemetry: runs-on: ubuntu-latest needs: release-please @@ -49,9 +66,12 @@ jobs: contents: write pull-requests: write if: ${{ needs.release-please.outputs.package-sdk-server-telemetry-released == 'true'}} + outputs: + hashes: ${{ steps.full-release.outputs.hashes }} steps: - uses: actions/checkout@v4 - uses: ./.github/actions/full-release + id: full-release with: workspace_path: 'pkgs/telemetry' project_file: 'pkgs/telemetry/src/LaunchDarkly.ServerSdk.Telemetry.csproj' @@ -61,3 +81,16 @@ jobs: dry_run: false aws_role: ${{ vars.AWS_ROLE_ARN }} token: ${{ secrets.GITHUB_TOKEN }} + + release-telemetry-provenance: + needs: ['release-please', 'release-telemetry'] + permissions: + actions: read + id-token: write + contents: write + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.10.0 + with: + base64-subjects: "${{ needs.release-telemetry.outputs.hashes }}" + upload-assets: true + upload-tag-name: ${{ needs.release-please.outputs.tag_name }} + provenance-name: ${{ format('LaunchDarkly.ServerSdk.Telemetry-{0}_provenance.intoto.jsonl', needs.release-please.outputs.tag_name) }}