diff --git a/.github/workflows/rust-build.yml b/.github/workflows/rust-build.yml index bbf8371..3905ff0 100644 --- a/.github/workflows/rust-build.yml +++ b/.github/workflows/rust-build.yml @@ -118,6 +118,14 @@ on: type: string default: "false" description: Force the publish test to be marked as non required + binary_sign_build: + type: string + default: "false" + description: Should the binary bin be signed + report_release: + type: string + default: "true" + description: Should the release be reported jobs: build_rust_ci_images: @@ -184,7 +192,7 @@ jobs: registry: ${{ inputs.docker_registry }} secrets: inherit publish_binary: - uses: ForesightMiningSoftwareCorporation/github/.github/workflows/rust_binary_publish.yml@v1 + uses: ForesightMiningSoftwareCorporation/github/.github/workflows/rust_binary_publish.yml@binary-signing if: always() && inputs.publish == 'true' && inputs.publish_binary == 'true' && (needs.test.result == 'success' || needs.test.result == 'skipped') needs: - test @@ -198,6 +206,7 @@ jobs: custom_cargo_commands: ${{ inputs.custom_cargo_commands }} matrix_file: ${{ inputs.matrix_file }} post_build_additional_script: ${{ inputs.post_build_additional_script }} + sign_build: ${{ inputs.binary_sign_build }} secrets: inherit report_release: needs: @@ -206,7 +215,7 @@ jobs: - publish_docker - publish_binary uses: ForesightMiningSoftwareCorporation/github/.github/workflows/gh-release-when-published.yaml@v1 - if: always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && inputs.publish == 'true' && ( inputs.publish_private_registry == 'false' || (inputs.publish_private_registry == 'true' && needs.publish_private_registry.outputs.released == 'true' )) && ( inputs.publish_public_registry == 'false' || ( inputs.publish_public_registry == 'true' && needs.publish_public_registry.outputs.released == 'true' )) && (inputs.publish_docker == 'false' || ( inputs.publish_docker == 'true' && needs.publish_docker.outputs.released == 'true' )) && (inputs.publish_binary == 'false' || inputs.publish_binary == 'true' ) + if: always() && inputs.report_release == 'true' && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && inputs.publish == 'true' && ( inputs.publish_private_registry == 'false' || (inputs.publish_private_registry == 'true' && needs.publish_private_registry.outputs.released == 'true' )) && ( inputs.publish_public_registry == 'false' || ( inputs.publish_public_registry == 'true' && needs.publish_public_registry.outputs.released == 'true' )) && (inputs.publish_docker == 'false' || ( inputs.publish_docker == 'true' && needs.publish_docker.outputs.released == 'true' )) && (inputs.publish_binary == 'false' || (inputs.publish_binary == 'true' && needs.publish_binary.outputs.released == 'true' )) with: working-directory: ${{ inputs.working-directory }} private_registry_release: ${{ inputs.publish_private_registry == 'true' && needs.publish_private_registry.outputs.released == 'true' }} diff --git a/.github/workflows/rust_binary_publish.yml b/.github/workflows/rust_binary_publish.yml index dc2ea45..69b815b 100644 --- a/.github/workflows/rust_binary_publish.yml +++ b/.github/workflows/rust_binary_publish.yml @@ -54,10 +54,10 @@ on: type: string default: "" description: Post Build Additional script to run after the additional packages - secrets: - github-private-keys: - required: false - description: Private keys that need to be added to the ssh-agent + sign_build: + type: string + default: "false" + description: Should the binary bin be signed env: CARGO_TERM_COLOR: always @@ -80,13 +80,13 @@ jobs: MATRIX=$(jq -c . < ${{ inputs.matrix_file }} | tr -d '^J') echo matrix=$MATRIX >> $GITHUB_OUTPUT cargo_upload_binary: - name: Upload binary to artifact storage + name: Release new version as binary strategy: matrix: os: ${{ fromJson(needs.matrix.outputs.matrix).os }} outputs: - released: ${{ steps.check_version_exists.outputs.exists == 'false' && 'true' || 'false' }} - runs-on: ${{ matrix.os.name }} + released: ${{ steps.check_exists.outputs.exists != 'true' && 'false' || 'true' }} + runs-on: ${{ matrix.os.name }}${{ matrix.os.runner_flavour }} needs: - matrix steps: @@ -287,3 +287,83 @@ jobs: connection_string: ${{ secrets.ARTIFACTS_CONNECTION_STRING }} source_folder: ${{ runner.temp }}/bin_output delete_if_exists: true + + - name: Generate Expiry for SAS Url + if: steps.check_exists.outputs.exists != 'true' && inputs.sign_build == 'true' + shell: bash + id: sas-expiry + run: | + echo "expiry=$(date -u -d "30 minutes" '+%Y-%m-%dT%H:%MZ')" >> $GITHUB_OUTPUT + + - name: Generate SAS Url for binary signing + if: steps.check_exists.outputs.exists != 'true' && inputs.sign_build == 'true' + shell: bash + id: sas-url + run: | + sas=$(az storage blob generate-sas --connection-string "${{ secrets.ARTIFACTS_CONNECTION_STRING }}" --container-name ${{ vars.ARTIFACTS_CONTAINER }} --name ${{ steps.read_name.outputs.value }}/${{ steps.extract_branch.outputs.release_channel }}/${{ steps.read_name.outputs.value }}-${{ matrix.os.arch }}-${{ inputs.toolchain }}-v${{ steps.read_version.outputs.value }}${{ matrix.os.extension }} --permissions r --expiry ${{ steps.sas-expiry.outputs.expiry }} --https-only --full-uri --output tsv) + echo "sas=$sas" >> $GITHUB_OUTPUT + + - name: Retrieve signing secret from Vault + if: steps.check_exists.outputs.exists != 'true' && inputs.sign_build == 'true' + id: import-signing-secrets + uses: hashicorp/vault-action@v2.7.3 + with: + method: jwt + url: ${{ vars.VAULT_ADDR }} + path: github + role: whirlpool-installer + secrets: | + kv-v2/data/whirlpool/signer PAT_TOKEN | WHIRLPOOL_SIGNER_PAT_TOKEN ; + kv-v2/data/whirlpool/signer REPOSITORY | WHIRLPOOL_SIGNER_REPOSITORY ; + + - name: Trigger signer workflow + if: steps.check_exists.outputs.exists != 'true' && inputs.sign_build == 'true' + uses: aurelien-baudet/workflow-dispatch@v2 + id: signer-workflow + with: + workflow: Sign File + token: ${{ steps.import-signing-secrets.outputs.WHIRLPOOL_SIGNER_PAT_TOKEN }} + ref: download-from-sas + run-name: "Sign ${{ steps.read_name.outputs.value }}-${{ matrix.os.arch }}-${{ inputs.toolchain }}-v${{ steps.read_version.outputs.value }}-signed${{ matrix.os.extension }}" + repo: ${{ steps.import-signing-secrets.outputs.WHIRLPOOL_SIGNER_REPOSITORY }} + inputs: '{"artifact_sas": "${{ steps.sas-url.outputs.sas }}", "artifact_name": "${{ steps.read_name.outputs.value }}-${{ matrix.os.arch }}-${{ inputs.toolchain }}-v${{ steps.read_version.outputs.value }}-signed${{ matrix.os.extension }}", "source_repository": "${{ github.repository }}", "source_run_id": "${{ github.run_id }}"}' + wait-for-completion: true + - name: Get signer workflow id + if: steps.check_exists.outputs.exists != 'true' && inputs.sign_build == 'true' + id: signer-workflow-id + shell: bash + run: | + url="${{ steps.signer-workflow.outputs.workflow-url }}" + echo "id=${url##*/}" >> $GITHUB_OUTPUT + - name: Download artifact to sign + if: steps.check_exists.outputs.exists != 'true' && inputs.sign_build == 'true' + id: download-artifact + uses: dawidd6/action-download-artifact@v2 + with: + github_token: ${{ steps.import-signing-secrets.outputs.WHIRLPOOL_SIGNER_PAT_TOKEN }} + repo: ${{ steps.import-signing-secrets.outputs.WHIRLPOOL_SIGNER_REPOSITORY }} + run_id: ${{ steps.signer-workflow-id.outputs.id }} + name: signed_artifacts + path: ${{ runner.temp }}/signed_artifacts/${{ steps.read_name.outputs.value }}/${{ steps.extract_branch.outputs.release_channel }} + + - name: Generate signed artifacts checksum + if: matrix.os.name == 'ubuntu-latest' && steps.check_exists.outputs.exists != 'true' && inputs.sign_build == 'true' + shell: bash + run: | + artifacts_dir=${{ runner.temp }}/signed_artifacts/${{ steps.read_name.outputs.value }}/${{ steps.extract_branch.outputs.release_channel }} + sha512sum $artifacts_dir/${{ steps.read_name.outputs.value }}-${{ matrix.os.arch }}-${{ inputs.toolchain }}-v${{ steps.read_version.outputs.value }}-signed${{ matrix.os.extension }} | awk '{ print $1 }' >> $artifacts_dir/${{ steps.read_name.outputs.value }}-${{ matrix.os.arch }}-${{ inputs.toolchain }}-v${{ steps.read_version.outputs.value }}${{ matrix.os.extension }}-signed-sha-512.txt + + - name: Copy to bin folder windows + if: matrix.os.name == 'windows-latest' && steps.check_exists.outputs.exists != 'true' && inputs.sign_build == 'true' + shell: pwsh + run: | + $hash = Get-FileHash "${{ runner.temp }}\signed_artifacts\${{ steps.read_name.outputs.value }}\${{ steps.extract_branch.outputs.release_channel }}\${{ steps.read_name.outputs.value }}-${{ matrix.os.arch }}-${{ inputs.toolchain }}-v${{ steps.read_version.outputs.value }}-signed${{ matrix.os.extension }}" -Algorithm SHA512 + echo $hash.Hash >> "${{ runner.temp }}\signed_artifacts\${{ steps.read_name.outputs.value }}\${{ steps.extract_branch.outputs.release_channel }}\${{ steps.read_name.outputs.value }}-${{ matrix.os.arch }}-${{ inputs.toolchain }}-v${{ steps.read_version.outputs.value }}-signed-sha512.txt" + - name: Upload signed artifacts to Azure Blob Upload + if: steps.check_exists.outputs.exists != 'true' && inputs.sign_build == 'true' + uses: LanceMcCarthy/Action-AzureBlobUpload@v2.2.1 + with: + container_name: ${{ vars.ARTIFACTS_CONTAINER }} + connection_string: ${{ secrets.ARTIFACTS_CONNECTION_STRING }} + source_folder: ${{ runner.temp }}/signed_artifacts + delete_if_exists: true