diff --git a/.github/actions/linux-code-sign/action.yml b/.github/actions/linux-code-sign/action.yml new file mode 100644 index 0000000000..0e237ddaf0 --- /dev/null +++ b/.github/actions/linux-code-sign/action.yml @@ -0,0 +1,39 @@ +name: linux-code-sign +description: Sign Linux artifacts with cosign. +inputs: + target: + description: Target triple for the artifacts to sign. + required: true + +runs: + using: composite + steps: + - name: Install cosign + uses: sigstore/cosign-installer@v3.7.0 + + - name: Cosign Linux artifacts + shell: bash + env: + COSIGN_EXPERIMENTAL: "1" + COSIGN_YES: "true" + COSIGN_OIDC_CLIENT_ID: "sigstore" + COSIGN_OIDC_ISSUER: "https://oauth2.sigstore.dev/auth" + run: | + set -euo pipefail + + dest="dist/${{ inputs.target }}" + if [[ ! -d "$dest" ]]; then + echo "Destination $dest does not exist" + exit 1 + fi + + shopt -s nullglob + for artifact in "$dest"/*; do + if [[ -f "$artifact" ]]; then + cosign sign-blob \ + --yes \ + --output-signature "${artifact}.sig" \ + --output-certificate "${artifact}.pem" \ + "$artifact" + fi + done diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index ae58536a72..3487dfe925 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -8,8 +8,6 @@ name: rust-release on: push: - branches: - - "**" tags: - "rust-v*.*.*" # DO NOT SUBMIT @@ -109,235 +107,192 @@ jobs: - name: Cargo build run: cargo build --target ${{ matrix.target }} --release --bin codex --bin codex-responses-api-proxy - - if: ${{ contains(matrix.target, 'linux') }} - name: Install cosign - uses: sigstore/cosign-installer@v3.7.0 - - if: ${{ contains(matrix.target, 'linux') }} name: Cosign Linux artifacts - shell: bash - env: - COSIGN_EXPERIMENTAL: "1" - COSIGN_YES: "true" - COSIGN_OIDC_CLIENT_ID: "sigstore" - COSIGN_OIDC_ISSUER: "https://oauth2.sigstore.dev/auth" - run: | - set -euo pipefail - - dest="dist/${{ matrix.target }}" - if [[ ! -d "$dest" ]]; then - echo "Destination $dest does not exist" - exit 1 - fi - - shopt -s nullglob - for artifact in "$dest"/*; do - if [[ -f "$artifact" ]]; then - cosign sign-blob \ - --yes \ - --output-signature "${artifact}.sig" \ - --output-certificate "${artifact}.pem" \ - "$artifact" - fi - done - - - if: ${{ contains(matrix.target, 'windows') }} - name: Azure login for Trusted Signing (OIDC) - uses: azure/login@v2 + uses: ./.github/actions/linux-code-sign with: - client-id: ${{ secrets.AZURE_TRUSTED_SIGNING_CLIENT_ID }} - tenant-id: ${{ secrets.AZURE_TRUSTED_SIGNING_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_TRUSTED_SIGNING_SUBSCRIPTION_ID }} + target: ${{ matrix.target }} - - if: ${{ contains(matrix.target, 'windows') }} - name: Sign Windows binaries with Azure Trusted Signing - uses: azure/trusted-signing-action@v0 - with: - endpoint: ${{ secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} - trusted-signing-account-name: ${{ secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} - certificate-profile-name: ${{ secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} - exclude-environment-credential: true - exclude-workload-identity-credential: true - exclude-managed-identity-credential: true - exclude-shared-token-cache-credential: true - exclude-visual-studio-credential: true - exclude-visual-studio-code-credential: true - exclude-azure-cli-credential: false - exclude-azure-powershell-credential: true - exclude-azure-developer-cli-credential: true - exclude-interactive-browser-credential: true - files: | - ${{ github.workspace }}/codex-rs/target/${{ matrix.target }}/release/codex.exe - ${{ github.workspace }}/codex-rs/target/${{ matrix.target }}/release/codex-responses-api-proxy.exe + # - if: ${{ contains(matrix.target, 'windows') }} + # name: Sign Windows binaries with Azure Trusted Signing + # uses: ./.github/actions/windows-code-sign + # with: + # target: ${{ matrix.target }} + # client-id: ${{ secrets.AZURE_TRUSTED_SIGNING_CLIENT_ID }} + # tenant-id: ${{ secrets.AZURE_TRUSTED_SIGNING_TENANT_ID }} + # subscription-id: ${{ secrets.AZURE_TRUSTED_SIGNING_SUBSCRIPTION_ID }} + # endpoint: ${{ secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} + # account-name: ${{ secrets.AZURE_TRUSTED_SIGNING_ACCOUNT_NAME }} + # certificate-profile: ${{ secrets.AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE }} - - if: ${{ matrix.runner == 'macos-15-xlarge' }} - name: Configure Apple code signing - shell: bash - env: - KEYCHAIN_PASSWORD: actions - APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE_P12 }} - APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} - run: | - set -euo pipefail + # - if: ${{ matrix.runner == 'macos-15-xlarge' }} + # name: Configure Apple code signing + # shell: bash + # env: + # KEYCHAIN_PASSWORD: actions + # APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE_P12 }} + # APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + # run: | + # set -euo pipefail - if [[ -z "${APPLE_CERTIFICATE:-}" ]]; then - echo "APPLE_CERTIFICATE is required for macOS signing" - exit 1 - fi + # if [[ -z "${APPLE_CERTIFICATE:-}" ]]; then + # echo "APPLE_CERTIFICATE is required for macOS signing" + # exit 1 + # fi - if [[ -z "${APPLE_CERTIFICATE_PASSWORD:-}" ]]; then - echo "APPLE_CERTIFICATE_PASSWORD is required for macOS signing" - exit 1 - fi + # if [[ -z "${APPLE_CERTIFICATE_PASSWORD:-}" ]]; then + # echo "APPLE_CERTIFICATE_PASSWORD is required for macOS signing" + # exit 1 + # fi - cert_path="${RUNNER_TEMP}/apple_signing_certificate.p12" - echo "$APPLE_CERTIFICATE" | base64 -d > "$cert_path" + # cert_path="${RUNNER_TEMP}/apple_signing_certificate.p12" + # echo "$APPLE_CERTIFICATE" | base64 -d > "$cert_path" - keychain_path="${RUNNER_TEMP}/codex-signing.keychain-db" - security create-keychain -p "$KEYCHAIN_PASSWORD" "$keychain_path" - security set-keychain-settings -lut 21600 "$keychain_path" - security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$keychain_path" + # keychain_path="${RUNNER_TEMP}/codex-signing.keychain-db" + # security create-keychain -p "$KEYCHAIN_PASSWORD" "$keychain_path" + # security set-keychain-settings -lut 21600 "$keychain_path" + # security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$keychain_path" - keychain_args=() - cleanup_keychain() { - if ((${#keychain_args[@]} > 0)); then - security list-keychains -s "${keychain_args[@]}" || true - security default-keychain -s "${keychain_args[0]}" || true - else - security list-keychains -s || true - fi - if [[ -f "$keychain_path" ]]; then - security delete-keychain "$keychain_path" || true - fi - } + # keychain_args=() + # cleanup_keychain() { + # if ((${#keychain_args[@]} > 0)); then + # security list-keychains -s "${keychain_args[@]}" || true + # security default-keychain -s "${keychain_args[0]}" || true + # else + # security list-keychains -s || true + # fi + # if [[ -f "$keychain_path" ]]; then + # security delete-keychain "$keychain_path" || true + # fi + # } - while IFS= read -r keychain; do - [[ -n "$keychain" ]] && keychain_args+=("$keychain") - done < <(security list-keychains | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/"//g') + # while IFS= read -r keychain; do + # [[ -n "$keychain" ]] && keychain_args+=("$keychain") + # done < <(security list-keychains | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/"//g') - if ((${#keychain_args[@]} > 0)); then - security list-keychains -s "$keychain_path" "${keychain_args[@]}" - else - security list-keychains -s "$keychain_path" - fi + # if ((${#keychain_args[@]} > 0)); then + # security list-keychains -s "$keychain_path" "${keychain_args[@]}" + # else + # security list-keychains -s "$keychain_path" + # fi - security default-keychain -s "$keychain_path" - security import "$cert_path" -k "$keychain_path" -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security - security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" "$keychain_path" > /dev/null + # security default-keychain -s "$keychain_path" + # security import "$cert_path" -k "$keychain_path" -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security + # security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" "$keychain_path" > /dev/null - codesign_hashes=() - while IFS= read -r hash; do - [[ -n "$hash" ]] && codesign_hashes+=("$hash") - done < <(security find-identity -v -p codesigning "$keychain_path" \ - | sed -n 's/.*\([0-9A-F]\{40\}\).*/\1/p' \ - | sort -u) + # codesign_hashes=() + # while IFS= read -r hash; do + # [[ -n "$hash" ]] && codesign_hashes+=("$hash") + # done < <(security find-identity -v -p codesigning "$keychain_path" \ + # | sed -n 's/.*\([0-9A-F]\{40\}\).*/\1/p' \ + # | sort -u) - if ((${#codesign_hashes[@]} == 0)); then - echo "No signing identities found in $keychain_path" - cleanup_keychain - rm -f "$cert_path" - exit 1 - fi + # if ((${#codesign_hashes[@]} == 0)); then + # echo "No signing identities found in $keychain_path" + # cleanup_keychain + # rm -f "$cert_path" + # exit 1 + # fi - if ((${#codesign_hashes[@]} > 1)); then - echo "Multiple signing identities found in $keychain_path:" - printf ' %s\n' "${codesign_hashes[@]}" - cleanup_keychain - rm -f "$cert_path" - exit 1 - fi + # if ((${#codesign_hashes[@]} > 1)); then + # echo "Multiple signing identities found in $keychain_path:" + # printf ' %s\n' "${codesign_hashes[@]}" + # cleanup_keychain + # rm -f "$cert_path" + # exit 1 + # fi - APPLE_CODESIGN_IDENTITY="${codesign_hashes[0]}" + # APPLE_CODESIGN_IDENTITY="${codesign_hashes[0]}" - rm -f "$cert_path" + # rm -f "$cert_path" - echo "APPLE_CODESIGN_IDENTITY=$APPLE_CODESIGN_IDENTITY" >> "$GITHUB_ENV" - echo "APPLE_CODESIGN_KEYCHAIN=$keychain_path" >> "$GITHUB_ENV" - echo "::add-mask::$APPLE_CODESIGN_IDENTITY" + # echo "APPLE_CODESIGN_IDENTITY=$APPLE_CODESIGN_IDENTITY" >> "$GITHUB_ENV" + # echo "APPLE_CODESIGN_KEYCHAIN=$keychain_path" >> "$GITHUB_ENV" + # echo "::add-mask::$APPLE_CODESIGN_IDENTITY" - - if: ${{ matrix.runner == 'macos-15-xlarge' }} - name: Sign macOS binaries - shell: bash - run: | - set -euo pipefail + # - if: ${{ matrix.runner == 'macos-15-xlarge' }} + # name: Sign macOS binaries + # shell: bash + # run: | + # set -euo pipefail - if [[ -z "${APPLE_CODESIGN_IDENTITY:-}" ]]; then - echo "APPLE_CODESIGN_IDENTITY is required for macOS signing" - exit 1 - fi + # if [[ -z "${APPLE_CODESIGN_IDENTITY:-}" ]]; then + # echo "APPLE_CODESIGN_IDENTITY is required for macOS signing" + # exit 1 + # fi - keychain_args=() - if [[ -n "${APPLE_CODESIGN_KEYCHAIN:-}" && -f "${APPLE_CODESIGN_KEYCHAIN}" ]]; then - keychain_args+=(--keychain "${APPLE_CODESIGN_KEYCHAIN}") - fi + # keychain_args=() + # if [[ -n "${APPLE_CODESIGN_KEYCHAIN:-}" && -f "${APPLE_CODESIGN_KEYCHAIN}" ]]; then + # keychain_args+=(--keychain "${APPLE_CODESIGN_KEYCHAIN}") + # fi - for binary in codex codex-responses-api-proxy; do - path="target/${{ matrix.target }}/release/${binary}" - codesign --force --options runtime --timestamp --sign "$APPLE_CODESIGN_IDENTITY" "${keychain_args[@]}" "$path" - done + # for binary in codex codex-responses-api-proxy; do + # path="target/${{ matrix.target }}/release/${binary}" + # codesign --force --options runtime --timestamp --sign "$APPLE_CODESIGN_IDENTITY" "${keychain_args[@]}" "$path" + # done - - if: ${{ matrix.runner == 'macos-15-xlarge' }} - name: Notarize macOS binaries - shell: bash - env: - APPLE_NOTARIZATION_KEY_P8: ${{ secrets.APPLE_NOTARIZATION_KEY_P8 }} - APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }} - APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }} - run: | - set -euo pipefail + # - if: ${{ matrix.runner == 'macos-15-xlarge' }} + # name: Notarize macOS binaries + # shell: bash + # env: + # APPLE_NOTARIZATION_KEY_P8: ${{ secrets.APPLE_NOTARIZATION_KEY_P8 }} + # APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }} + # APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }} + # run: | + # set -euo pipefail - for var in APPLE_NOTARIZATION_KEY_P8 APPLE_NOTARIZATION_KEY_ID APPLE_NOTARIZATION_ISSUER_ID; do - if [[ -z "${!var:-}" ]]; then - echo "$var is required for notarization" - exit 1 - fi - done + # for var in APPLE_NOTARIZATION_KEY_P8 APPLE_NOTARIZATION_KEY_ID APPLE_NOTARIZATION_ISSUER_ID; do + # if [[ -z "${!var:-}" ]]; then + # echo "$var is required for notarization" + # exit 1 + # fi + # done - notary_key_path="${RUNNER_TEMP}/notarytool.key.p8" - echo "$APPLE_NOTARIZATION_KEY_P8" | base64 -d > "$notary_key_path" - cleanup_notary() { - rm -f "$notary_key_path" - } - trap cleanup_notary EXIT + # notary_key_path="${RUNNER_TEMP}/notarytool.key.p8" + # echo "$APPLE_NOTARIZATION_KEY_P8" | base64 -d > "$notary_key_path" + # cleanup_notary() { + # rm -f "$notary_key_path" + # } + # trap cleanup_notary EXIT - notarize_binary() { - local binary="$1" - local source_path="target/${{ matrix.target }}/release/${binary}" - local archive_path="${RUNNER_TEMP}/${binary}.zip" + # notarize_binary() { + # local binary="$1" + # local source_path="target/${{ matrix.target }}/release/${binary}" + # local archive_path="${RUNNER_TEMP}/${binary}.zip" - if [[ ! -f "$source_path" ]]; then - echo "Binary $source_path not found" - exit 1 - fi + # if [[ ! -f "$source_path" ]]; then + # echo "Binary $source_path not found" + # exit 1 + # fi - rm -f "$archive_path" - ditto -c -k --keepParent "$source_path" "$archive_path" + # rm -f "$archive_path" + # ditto -c -k --keepParent "$source_path" "$archive_path" - submission_json=$(xcrun notarytool submit "$archive_path" \ - --key "$notary_key_path" \ - --key-id "$APPLE_NOTARIZATION_KEY_ID" \ - --issuer "$APPLE_NOTARIZATION_ISSUER_ID" \ - --output-format json \ - --wait) + # submission_json=$(xcrun notarytool submit "$archive_path" \ + # --key "$notary_key_path" \ + # --key-id "$APPLE_NOTARIZATION_KEY_ID" \ + # --issuer "$APPLE_NOTARIZATION_ISSUER_ID" \ + # --output-format json \ + # --wait) - status=$(printf '%s\n' "$submission_json" | jq -r '.status // "Unknown"') - submission_id=$(printf '%s\n' "$submission_json" | jq -r '.id // ""') + # status=$(printf '%s\n' "$submission_json" | jq -r '.status // "Unknown"') + # submission_id=$(printf '%s\n' "$submission_json" | jq -r '.id // ""') - if [[ -z "$submission_id" ]]; then - echo "Failed to retrieve submission ID for $binary" - exit 1 - fi + # if [[ -z "$submission_id" ]]; then + # echo "Failed to retrieve submission ID for $binary" + # exit 1 + # fi - echo "::notice title=Notarization::$binary submission ${submission_id} completed with status ${status}" + # echo "::notice title=Notarization::$binary submission ${submission_id} completed with status ${status}" - if [[ "$status" != "Accepted" ]]; then - echo "Notarization failed for ${binary} (submission ${submission_id}, status ${status})" - exit 1 - fi - } + # if [[ "$status" != "Accepted" ]]; then + # echo "Notarization failed for ${binary} (submission ${submission_id}, status ${status})" + # exit 1 + # fi + # } - notarize_binary "codex" - notarize_binary "codex-responses-api-proxy" + # notarize_binary "codex" + # notarize_binary "codex-responses-api-proxy" - name: Stage artifacts shell: bash @@ -420,28 +375,28 @@ jobs: zstd "${zstd_args[@]}" "$dest/$base" done - - name: Remove signing keychain - if: ${{ always() && matrix.runner == 'macos-15-xlarge' }} - shell: bash - env: - APPLE_CODESIGN_KEYCHAIN: ${{ env.APPLE_CODESIGN_KEYCHAIN }} - run: | - set -euo pipefail - if [[ -n "${APPLE_CODESIGN_KEYCHAIN:-}" ]]; then - keychain_args=() - while IFS= read -r keychain; do - [[ "$keychain" == "$APPLE_CODESIGN_KEYCHAIN" ]] && continue - [[ -n "$keychain" ]] && keychain_args+=("$keychain") - done < <(security list-keychains | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/"//g') - if ((${#keychain_args[@]} > 0)); then - security list-keychains -s "${keychain_args[@]}" - security default-keychain -s "${keychain_args[0]}" - fi + # - name: Remove signing keychain + # if: ${{ always() && matrix.runner == 'macos-15-xlarge' }} + # shell: bash + # env: + # APPLE_CODESIGN_KEYCHAIN: ${{ env.APPLE_CODESIGN_KEYCHAIN }} + # run: | + # set -euo pipefail + # if [[ -n "${APPLE_CODESIGN_KEYCHAIN:-}" ]]; then + # keychain_args=() + # while IFS= read -r keychain; do + # [[ "$keychain" == "$APPLE_CODESIGN_KEYCHAIN" ]] && continue + # [[ -n "$keychain" ]] && keychain_args+=("$keychain") + # done < <(security list-keychains | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/"//g') + # if ((${#keychain_args[@]} > 0)); then + # security list-keychains -s "${keychain_args[@]}" + # security default-keychain -s "${keychain_args[0]}" + # fi - if [[ -f "$APPLE_CODESIGN_KEYCHAIN" ]]; then - security delete-keychain "$APPLE_CODESIGN_KEYCHAIN" - fi - fi + # if [[ -f "$APPLE_CODESIGN_KEYCHAIN" ]]; then + # security delete-keychain "$APPLE_CODESIGN_KEYCHAIN" + # fi + # fi - uses: actions/upload-artifact@v5 with: