Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion clients/cli/.github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,55 @@ jobs:
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ steps.version.outputs.VERSION }}
- name: Upload built binaries
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
- name: Create draft GitHub Release
uses: softprops/action-gh-release@v1
with:
draft: true
name: ${{ github.ref_name }}
tag_name: ${{ github.ref_name }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

sign_and_notarize:
runs-on: macos-latest
needs: release
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download built binaries
uses: actions/download-artifact@v4
with:
name: dist
path: dist
- name: Sign CLI binaries
run: bash ./build/sign.sh
env:
SIGNING_CERTIFICATE: ${{ secrets.SIGNING_CERTIFICATE }}
CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATE_PASSWORD }}
SIGNING_IDENTITY: ${{ secrets.SIGNING_IDENTITY }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
DIST_DIR: "dist"
- name: Upload signed binaries to Draft Release
uses: softprops/action-gh-release@v1
with:
files: dist/*
name: ${{ github.ref_name }}
tag_name: ${{ github.ref_name }}
draft: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Publish GitHub Release
run: gh release edit ${{ github.ref_name }} --draft=false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
brew:
runs-on: ubuntu-latest
needs: release
needs: sign_and_notarize
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
50 changes: 1 addition & 49 deletions clients/cli/build/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,52 +25,4 @@ cp dist/phrase_linux_arm64 dist/linux/arm64

docker buildx build --tag "${IMAGE}" --tag ${IMAGE_LATEST} --platform linux/amd64,linux/arm64 -f ./Dockerfile --push .

# Create release
function create_release_data()
{
cat <<EOF
{
"tag_name": "${VERSION}",
"name": "${VERSION}",
"draft": true,
"prerelease": false,
"body": "https://github.com/phrase/phrase-cli/blob/master/CHANGELOG.md"
}
EOF
}

echo "Create release $VERSION"
api_url="https://api.github.com/repos/phrase/phrase-cli/releases"
response="$(curl -H "Authorization: token ${GITHUB_TOKEN}" --data "$(create_release_data)" ${api_url})"
release_id=$(echo $response | python -c "import sys, json; print(json.load(sys.stdin).get('id', ''))")

if [ -z "$release_id" ]
then
echo "Failed to create GitHub release"
echo $response
exit 1
else
echo "New release created created with id: ${release_id}"
fi

# Upload artifacts
DIST_DIR="./dist"
for file in "$DIST_DIR"/*; do
if [ -f "$file" ]; then
echo "Uploading ${file}"
asset="https://uploads.github.com/repos/phrase/phrase-cli/releases/${release_id}/assets?name=$(basename "$file")"
curl -sS --data-binary @"$file" -H "Authorization: token ${GITHUB_TOKEN}" -H "Content-Type: application/octet-stream" $asset > /dev/null
echo Hash: $(sha256sum $file)
fi
done

echo "Publishing release"
curl \
--silent \
-X PATCH \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/phrase/phrase-cli/releases/${release_id}" \
-d '{"draft": false}' > /dev/null

echo "Release successful"
echo "Artifacts built and ready in dist/ directory. GitHub Release creation handled in GitHub Actions workflow."
37 changes: 37 additions & 0 deletions clients/cli/build/sign.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash
set -eo pipefail

CERTIFICATE_BASE64="${SIGNING_CERTIFICATE}"
P12_PASSWORD="${CERTIFICATE_PASSWORD}"
SIGNING_IDENTITY="${SIGNING_IDENTITY}"
KEYCHAIN_PASSWORD="${KEYCHAIN_PASSWORD}"
DIST_DIR="${DIST_DIR:-dist}"

CERTIFICATE_PATH="./build_certificate.p12"
KEYCHAIN_PATH="./my-signing.keychain-db"

echo "🔐 Setting up certificate and keychain..."

# Decode the certificate
echo "$CERTIFICATE_BASE64" | base64 --decode -o "$CERTIFICATE_PATH"

# Create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"

# Import certificate into keychain
security import "$CERTIFICATE_PATH" -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH"
security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security list-keychain -d user -s "$KEYCHAIN_PATH"

# Find and sign all macOS binaries dynamically
echo "🔎 Searching for macOS binaries in $DIST_DIR..."

find "$DIST_DIR" -type f \( -name "phrase_macosx_*" ! -name "*.tar.gz" \) | while read -r binary; do
echo "🔏 Signing $binary..."
codesign --timestamp --options runtime --sign "$SIGNING_IDENTITY" "$binary"
codesign --verify --verbose=2 "$binary"
done

echo "✅ All macOS binaries signed successfully."
Loading