@@ -25,10 +25,149 @@ jobs:
2525 ref : prod
2626 fetch-depth : 0
2727
28+ - name : Setup SSH signing key
29+ run : |
30+ echo "🔍 Setting up SSH signing key..."
31+
32+ # Create SSH directory
33+ mkdir -p ~/.ssh
34+ chmod 700 ~/.ssh
35+
36+ # Use SSH signing key from secrets
37+ if [ -n "${{ secrets.SSH_KEY }}" ]; then
38+ echo " SSH_KEY secret found"
39+
40+ # Write the private key to file
41+ echo "${{ secrets.SSH_KEY }}" > ~/.ssh/id_ed25519
42+ chmod 600 ~/.ssh/id_ed25519
43+
44+ # Verify key file was created
45+ if [ -f ~/.ssh/id_ed25519 ]; then
46+ KEY_SIZE=$(wc -c < ~/.ssh/id_ed25519)
47+ LINE_COUNT=$(wc -l < ~/.ssh/id_ed25519)
48+ echo " Private key file created"
49+ echo " File size: ${KEY_SIZE} bytes"
50+ echo " Line count: ${LINE_COUNT} lines"
51+
52+ # Check if key starts with correct header
53+ FIRST_LINE=$(head -n 1 ~/.ssh/id_ed25519)
54+ LAST_LINE=$(tail -n 1 ~/.ssh/id_ed25519)
55+
56+ echo " First line: ${FIRST_LINE}"
57+ echo " Last line: ${LAST_LINE}"
58+
59+ if [[ "$FIRST_LINE" == *"BEGIN"* ]]; then
60+ echo " Key has correct BEGIN header"
61+ else
62+ echo " ERROR: Key does NOT start with BEGIN header"
63+ echo ""
64+ echo " Key file content (first 3 lines):"
65+ head -n 3 ~/.ssh/id_ed25519
66+ echo ""
67+ echo "Expected format:"
68+ echo "-----BEGIN OPENSSH PRIVATE KEY-----"
69+ echo "b3BlbnNzaC1rZXktdjEAAAAA..."
70+ echo "-----END OPENSSH PRIVATE KEY-----"
71+ exit 1
72+ fi
73+
74+ if [[ "$LAST_LINE" == *"END"* ]]; then
75+ echo " Key has correct END footer"
76+ else
77+ echo " WARNING: Key might not have correct END footer"
78+ fi
79+ else
80+ echo " ERROR: Failed to create private key file"
81+ exit 1
82+ fi
83+
84+ # Extract public key from private key
85+ echo ""
86+ echo "🔍 Extracting public key from private key..."
87+
88+ # Capture both stdout and stderr
89+ PUB_KEY_OUTPUT=$(ssh-keygen -y -f ~/.ssh/id_ed25519 2>&1)
90+ PUB_KEY_EXIT_CODE=$?
91+
92+ if [ $PUB_KEY_EXIT_CODE -eq 0 ]; then
93+ echo "$PUB_KEY_OUTPUT" > ~/.ssh/id_ed25519.pub
94+ chmod 644 ~/.ssh/id_ed25519.pub
95+ echo " Public key extracted successfully"
96+ echo " Public key type: $(echo "$PUB_KEY_OUTPUT" | cut -d' ' -f1)"
97+ else
98+ echo " ERROR: Failed to extract public key"
99+ echo ""
100+ echo " Detailed error from ssh-keygen:"
101+ echo "$PUB_KEY_OUTPUT"
102+ echo ""
103+ echo " Checking key file integrity:"
104+ echo " File exists: $([ -f ~/.ssh/id_ed25519 ] && echo 'Yes' || echo 'No')"
105+ echo " File size: $(wc -c < ~/.ssh/id_ed25519) bytes"
106+ echo " File permissions: $(ls -l ~/.ssh/id_ed25519 | awk '{print $1}')"
107+ echo " First 50 chars: $(head -c 50 ~/.ssh/id_ed25519)"
108+ echo ""
109+ echo " Common issues:"
110+ echo " 1. Key is encrypted with a passphrase (GitHub Actions can't use those)"
111+ echo " 2. Key format is corrupted during copy/paste"
112+ echo " 3. Wrong key type (must be ed25519 or rsa)"
113+ echo " 4. Key file has Windows line endings (CRLF instead of LF)"
114+ echo ""
115+ echo "🔧 How to fix:"
116+ echo " 1. Check if your key has a passphrase: ssh-keygen -y -f ~/.ssh/id_ed25519"
117+ echo " 2. If it asks for passphrase, create a new key WITHOUT passphrase:"
118+ echo " ssh-keygen -t ed25519 -C 'your_email@example.com' -N '' -f ~/.ssh/id_ed25519_nopass"
119+ echo " 3. Add the NEW key's public key to your GitHub account"
120+ echo " 4. Update SSH_KEY secret with the NEW private key"
121+ exit 1
122+ fi
123+ else
124+ echo " ERROR: SSH_KEY secret not found"
125+ echo ""
126+ echo "Please add your SSH signing key as a repository secret:"
127+ echo " Secret name: SSH_KEY"
128+ echo " Secret value: Your SSH private key (from ~/.ssh/id_ed25519)"
129+ echo ""
130+ echo "Steps:"
131+ echo " 1. Get your private key: cat ~/.ssh/id_ed25519"
132+ echo " 2. Go to: Repository Settings → Secrets and variables → Actions"
133+ echo " 3. Click: New repository secret"
134+ echo " 4. Name: SSH_KEY"
135+ echo " 5. Value: Paste your entire private key (including BEGIN/END lines)"
136+ echo " 6. Click: Add secret"
137+ exit 1
138+ fi
139+
140+ echo " SSH signing key configured for ${{ github.actor }}"
141+
28142 - name : Configure Git
29143 run : |
144+ echo " Configuring Git for signed commits..."
145+
30146 git config user.name "${{ github.actor }}"
31147 git config user.email "${{ github.actor }}@users.noreply.github.com"
148+
149+ # Configure commit signing
150+ git config commit.gpgsign true
151+ git config gpg.format ssh
152+ git config user.signingkey ~/.ssh/id_ed25519.pub
153+
154+ # Verify Git configuration
155+ echo " Git Configuration:"
156+ echo " User: $(git config user.name)"
157+ echo " Email: $(git config user.email)"
158+ echo " Signing: $(git config commit.gpgsign)"
159+ echo " GPG Format: $(git config gpg.format)"
160+ echo " Signing Key: $(git config user.signingkey)"
161+
162+ # Verify signing key file exists
163+ if [ -f ~/.ssh/id_ed25519.pub ]; then
164+ echo " Signing key file exists"
165+ else
166+ echo " ERROR: Signing key file not found!"
167+ exit 1
168+ fi
169+
170+ echo " Git configured for signed commits by ${{ github.actor }}"
32171 - name : Prepare translation branch
33172 run : |
34173 if git ls-remote --heads origin blog_translation_automation | grep blog_translation_automation; then
37176 fi
38177 git checkout -b blog_translation_automation
39178 git push origin blog_translation_automation
40- echo "✅ Translation branch ready"
179+ echo " Translation branch ready"
41180 - name : Setup Node.js
42181 uses : actions/setup-node@v4
43182 with :
54193 if [ -f ~/.bash_profile ]; then source ~/.bash_profile; fi
55194 if [ -f ~/.profile ]; then source ~/.profile; fi
56195
57- echo "✅ IBM BOB installed successfully"
196+ echo " IBM BOB installed successfully"
58197 - name : Generate translation
59198 env :
60199 BOBSHELL_API_KEY : ${{ secrets.BOBSHELL_API_KEY }}
@@ -81,34 +220,98 @@ jobs:
81220
82221 TRANSLATION_EXIT_CODE=$?
83222 if [ $TRANSLATION_EXIT_CODE -ne 0 ]; then
84- echo "❌ Translation process encountered an error"
85- echo "Last 20 lines of output:"
223+ echo " Translation process failed"
224+ echo ""
225+ echo " Error Details:"
86226 tail -20 /tmp/translation.log
227+ echo ""
228+ echo "⚠️ Possible causes:"
229+ echo " • Insufficient Bob API credits/quota"
230+ echo " • Network connectivity issues"
231+ echo " • Invalid API key"
232+ echo " • File not found or inaccessible"
233+ echo ""
234+ echo " Next steps:"
235+ echo " 1. Check your Bob API credit balance"
236+ echo " 2. Verify BOBSHELL_API_KEY secret is valid"
237+ echo " 3. Review the error details above"
238+ echo " 4. Check if the blog file exists in posts/ directory"
239+ echo ""
87240 exit 1
88241 fi
89242
90243 # Verify translation output
91244 TRANSLATED_FILE="posts/ja/${BASE_FILENAME}.adoc"
245+ echo " Verifying translation output..."
246+ echo " Expected file: $TRANSLATED_FILE"
247+
92248 if [ -f "$TRANSLATED_FILE" ]; then
93- echo "✅ Translation completed successfully"
94- echo "Output: $TRANSLATED_FILE ($(stat -f%z "$TRANSLATED_FILE" 2>/dev/null || stat -c%s "$TRANSLATED_FILE") bytes)"
249+ FILE_SIZE=$(stat -f%z "$TRANSLATED_FILE" 2>/dev/null || stat -c%s "$TRANSLATED_FILE")
250+ echo " Translation completed successfully"
251+ echo " Output: $TRANSLATED_FILE"
252+ echo " Size: ${FILE_SIZE} bytes"
253+
254+ # Show first few lines of translated file
255+ echo ""
256+ echo " First 5 lines of translated file:"
257+ head -5 "$TRANSLATED_FILE"
95258 else
96- echo "❌ Translation failed: Output file not found"
259+ echo " Translation failed: Output file not found"
260+ echo ""
261+ echo " Checking posts/ja/ directory:"
262+ ls -la posts/ja/ || echo " Directory doesn't exist or is empty"
263+ echo ""
264+ echo " Full translation log:"
265+ cat /tmp/translation.log
97266 exit 1
98267 fi
99268 - name : Commit and push translation
100269 id : commit-changes
101270 run : |
271+ echo " Committing and pushing translation..."
272+
102273 git checkout blog_translation_automation
103274 git add posts/ja/*.adoc
104275
105276 if git diff --staged --quiet; then
106- echo "No changes detected"
277+ echo " No changes detected"
107278 echo "has_changes=false" >> $GITHUB_OUTPUT
108279 else
280+ echo " Creating signed commit..."
281+
282+ # Show what will be committed
283+ echo "Files to commit:"
284+ git diff --staged --name-only
285+
286+ # Create the commit
109287 git commit -m "Add Japanese translation for blog ${{ inputs.filename }}" --author "${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>"
288+
289+ # Verify commit was signed
290+ COMMIT_HASH=$(git rev-parse HEAD)
291+ echo ""
292+ echo " Commit Details:"
293+ echo " Hash: ${COMMIT_HASH}"
294+ echo " Author: $(git log -1 --format='%an <%ae>')"
295+ echo " Message: $(git log -1 --format='%s')"
296+
297+ # Check if commit is signed
298+ if git log -1 --format='%G?' | grep -q 'G\|U'; then
299+ echo " Commit is signed"
300+ else
301+ echo " WARNING: Commit is NOT signed!"
302+ echo " Signature status: $(git log -1 --format='%G?')"
303+ echo ""
304+ echo " Debugging info:"
305+ echo " Git signing config: $(git config commit.gpgsign)"
306+ echo " GPG format: $(git config gpg.format)"
307+ echo " Signing key: $(git config user.signingkey)"
308+ echo " Key file exists: $([ -f ~/.ssh/id_ed25519.pub ] && echo 'Yes' || echo 'No')"
309+ fi
310+
311+ echo ""
312+ echo " Pushing to remote..."
110313 git push origin blog_translation_automation
111- echo "✅ Translation committed successfully"
314+ echo " Translation committed and pushed successfully"
112315 echo "has_changes=true" >> $GITHUB_OUTPUT
113316 fi
114317 - name: Create pull request
@@ -143,6 +346,6 @@ jobs:
143346
144347 ---
145348 *Automated translation workflow triggered by @${{ github.actor }}*"
146- echo "✅ Pull request created successfully"
349+ echo " Pull request created successfully"
350+
147351
148- # Made with Bob
0 commit comments