diff --git a/.github/workflows/blog_translation_automation.yml b/.github/workflows/blog_translation_automation.yml index 6d1b03bc9..16ae9c323 100644 --- a/.github/workflows/blog_translation_automation.yml +++ b/.github/workflows/blog_translation_automation.yml @@ -25,10 +25,149 @@ jobs: ref: prod fetch-depth: 0 + - name: Setup SSH signing key + run: | + echo "🔍 Setting up SSH signing key..." + + # Create SSH directory + mkdir -p ~/.ssh + chmod 700 ~/.ssh + + # Use SSH signing key from secrets + if [ -n "${{ secrets.SSH_KEY }}" ]; then + echo " SSH_KEY secret found" + + # Write the private key to file + echo "${{ secrets.SSH_KEY }}" > ~/.ssh/id_ed25519 + chmod 600 ~/.ssh/id_ed25519 + + # Verify key file was created + if [ -f ~/.ssh/id_ed25519 ]; then + KEY_SIZE=$(wc -c < ~/.ssh/id_ed25519) + LINE_COUNT=$(wc -l < ~/.ssh/id_ed25519) + echo " Private key file created" + echo " File size: ${KEY_SIZE} bytes" + echo " Line count: ${LINE_COUNT} lines" + + # Check if key starts with correct header + FIRST_LINE=$(head -n 1 ~/.ssh/id_ed25519) + LAST_LINE=$(tail -n 1 ~/.ssh/id_ed25519) + + echo " First line: ${FIRST_LINE}" + echo " Last line: ${LAST_LINE}" + + if [[ "$FIRST_LINE" == *"BEGIN"* ]]; then + echo " Key has correct BEGIN header" + else + echo " ERROR: Key does NOT start with BEGIN header" + echo "" + echo " Key file content (first 3 lines):" + head -n 3 ~/.ssh/id_ed25519 + echo "" + echo "Expected format:" + echo "-----BEGIN OPENSSH PRIVATE KEY-----" + echo "b3BlbnNzaC1rZXktdjEAAAAA..." + echo "-----END OPENSSH PRIVATE KEY-----" + exit 1 + fi + + if [[ "$LAST_LINE" == *"END"* ]]; then + echo " Key has correct END footer" + else + echo " WARNING: Key might not have correct END footer" + fi + else + echo " ERROR: Failed to create private key file" + exit 1 + fi + + # Extract public key from private key + echo "" + echo "🔍 Extracting public key from private key..." + + # Capture both stdout and stderr + PUB_KEY_OUTPUT=$(ssh-keygen -y -f ~/.ssh/id_ed25519 2>&1) + PUB_KEY_EXIT_CODE=$? + + if [ $PUB_KEY_EXIT_CODE -eq 0 ]; then + echo "$PUB_KEY_OUTPUT" > ~/.ssh/id_ed25519.pub + chmod 644 ~/.ssh/id_ed25519.pub + echo " Public key extracted successfully" + echo " Public key type: $(echo "$PUB_KEY_OUTPUT" | cut -d' ' -f1)" + else + echo " ERROR: Failed to extract public key" + echo "" + echo " Detailed error from ssh-keygen:" + echo "$PUB_KEY_OUTPUT" + echo "" + echo " Checking key file integrity:" + echo " File exists: $([ -f ~/.ssh/id_ed25519 ] && echo 'Yes' || echo 'No')" + echo " File size: $(wc -c < ~/.ssh/id_ed25519) bytes" + echo " File permissions: $(ls -l ~/.ssh/id_ed25519 | awk '{print $1}')" + echo " First 50 chars: $(head -c 50 ~/.ssh/id_ed25519)" + echo "" + echo " Common issues:" + echo " 1. Key is encrypted with a passphrase (GitHub Actions can't use those)" + echo " 2. Key format is corrupted during copy/paste" + echo " 3. Wrong key type (must be ed25519 or rsa)" + echo " 4. Key file has Windows line endings (CRLF instead of LF)" + echo "" + echo "🔧 How to fix:" + echo " 1. Check if your key has a passphrase: ssh-keygen -y -f ~/.ssh/id_ed25519" + echo " 2. If it asks for passphrase, create a new key WITHOUT passphrase:" + echo " ssh-keygen -t ed25519 -C 'your_email@example.com' -N '' -f ~/.ssh/id_ed25519_nopass" + echo " 3. Add the NEW key's public key to your GitHub account" + echo " 4. Update SSH_KEY secret with the NEW private key" + exit 1 + fi + else + echo " ERROR: SSH_KEY secret not found" + echo "" + echo "Please add your SSH signing key as a repository secret:" + echo " Secret name: SSH_KEY" + echo " Secret value: Your SSH private key (from ~/.ssh/id_ed25519)" + echo "" + echo "Steps:" + echo " 1. Get your private key: cat ~/.ssh/id_ed25519" + echo " 2. Go to: Repository Settings → Secrets and variables → Actions" + echo " 3. Click: New repository secret" + echo " 4. Name: SSH_KEY" + echo " 5. Value: Paste your entire private key (including BEGIN/END lines)" + echo " 6. Click: Add secret" + exit 1 + fi + + echo " SSH signing key configured for ${{ github.actor }}" + - name: Configure Git run: | + echo " Configuring Git for signed commits..." + git config user.name "${{ github.actor }}" git config user.email "${{ github.actor }}@users.noreply.github.com" + + # Configure commit signing + git config commit.gpgsign true + git config gpg.format ssh + git config user.signingkey ~/.ssh/id_ed25519.pub + + # Verify Git configuration + echo " Git Configuration:" + echo " User: $(git config user.name)" + echo " Email: $(git config user.email)" + echo " Signing: $(git config commit.gpgsign)" + echo " GPG Format: $(git config gpg.format)" + echo " Signing Key: $(git config user.signingkey)" + + # Verify signing key file exists + if [ -f ~/.ssh/id_ed25519.pub ]; then + echo " Signing key file exists" + else + echo " ERROR: Signing key file not found!" + exit 1 + fi + + echo " Git configured for signed commits by ${{ github.actor }}" - name: Prepare translation branch run: | if git ls-remote --heads origin blog_translation_automation | grep blog_translation_automation; then @@ -37,7 +176,7 @@ jobs: fi git checkout -b blog_translation_automation git push origin blog_translation_automation - echo "✅ Translation branch ready" + echo " Translation branch ready" - name: Setup Node.js uses: actions/setup-node@v4 with: @@ -54,7 +193,7 @@ jobs: if [ -f ~/.bash_profile ]; then source ~/.bash_profile; fi if [ -f ~/.profile ]; then source ~/.profile; fi - echo "✅ IBM BOB installed successfully" + echo " IBM BOB installed successfully" - name: Generate translation env: BOBSHELL_API_KEY: ${{ secrets.BOBSHELL_API_KEY }} @@ -81,34 +220,98 @@ jobs: TRANSLATION_EXIT_CODE=$? if [ $TRANSLATION_EXIT_CODE -ne 0 ]; then - echo "❌ Translation process encountered an error" - echo "Last 20 lines of output:" + echo " Translation process failed" + echo "" + echo " Error Details:" tail -20 /tmp/translation.log + echo "" + echo "⚠️ Possible causes:" + echo " • Insufficient Bob API credits/quota" + echo " • Network connectivity issues" + echo " • Invalid API key" + echo " • File not found or inaccessible" + echo "" + echo " Next steps:" + echo " 1. Check your Bob API credit balance" + echo " 2. Verify BOBSHELL_API_KEY secret is valid" + echo " 3. Review the error details above" + echo " 4. Check if the blog file exists in posts/ directory" + echo "" exit 1 fi # Verify translation output TRANSLATED_FILE="posts/ja/${BASE_FILENAME}.adoc" + echo " Verifying translation output..." + echo " Expected file: $TRANSLATED_FILE" + if [ -f "$TRANSLATED_FILE" ]; then - echo "✅ Translation completed successfully" - echo "Output: $TRANSLATED_FILE ($(stat -f%z "$TRANSLATED_FILE" 2>/dev/null || stat -c%s "$TRANSLATED_FILE") bytes)" + FILE_SIZE=$(stat -f%z "$TRANSLATED_FILE" 2>/dev/null || stat -c%s "$TRANSLATED_FILE") + echo " Translation completed successfully" + echo " Output: $TRANSLATED_FILE" + echo " Size: ${FILE_SIZE} bytes" + + # Show first few lines of translated file + echo "" + echo " First 5 lines of translated file:" + head -5 "$TRANSLATED_FILE" else - echo "❌ Translation failed: Output file not found" + echo " Translation failed: Output file not found" + echo "" + echo " Checking posts/ja/ directory:" + ls -la posts/ja/ || echo " Directory doesn't exist or is empty" + echo "" + echo " Full translation log:" + cat /tmp/translation.log exit 1 fi - name: Commit and push translation id: commit-changes run: | + echo " Committing and pushing translation..." + git checkout blog_translation_automation git add posts/ja/*.adoc if git diff --staged --quiet; then - echo "No changes detected" + echo " No changes detected" echo "has_changes=false" >> $GITHUB_OUTPUT else + echo " Creating signed commit..." + + # Show what will be committed + echo "Files to commit:" + git diff --staged --name-only + + # Create the commit git commit -m "Add Japanese translation for blog ${{ inputs.filename }}" --author "${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>" + + # Verify commit was signed + COMMIT_HASH=$(git rev-parse HEAD) + echo "" + echo " Commit Details:" + echo " Hash: ${COMMIT_HASH}" + echo " Author: $(git log -1 --format='%an <%ae>')" + echo " Message: $(git log -1 --format='%s')" + + # Check if commit is signed + if git log -1 --format='%G?' | grep -q 'G\|U'; then + echo " Commit is signed" + else + echo " WARNING: Commit is NOT signed!" + echo " Signature status: $(git log -1 --format='%G?')" + echo "" + echo " Debugging info:" + echo " Git signing config: $(git config commit.gpgsign)" + echo " GPG format: $(git config gpg.format)" + echo " Signing key: $(git config user.signingkey)" + echo " Key file exists: $([ -f ~/.ssh/id_ed25519.pub ] && echo 'Yes' || echo 'No')" + fi + + echo "" + echo " Pushing to remote..." git push origin blog_translation_automation - echo "✅ Translation committed successfully" + echo " Translation committed and pushed successfully" echo "has_changes=true" >> $GITHUB_OUTPUT fi - name: Create pull request @@ -143,6 +346,6 @@ jobs: --- *Automated translation workflow triggered by @${{ github.actor }}*" - echo "✅ Pull request created successfully" + echo " Pull request created successfully" + -# Made with Bob