From 7c4f0707cc17f879bf44d7a603bcd1d0c21a8f2f Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin Date: Wed, 26 Nov 2025 09:35:55 +0200 Subject: [PATCH 01/16] Test slack notification --- .github/workflows/daily-test-matrix.yml | 249 ++++++++++++++++++++++++ 1 file changed, 249 insertions(+) diff --git a/.github/workflows/daily-test-matrix.yml b/.github/workflows/daily-test-matrix.yml index eef76016..fc581c4c 100644 --- a/.github/workflows/daily-test-matrix.yml +++ b/.github/workflows/daily-test-matrix.yml @@ -89,6 +89,73 @@ jobs: targeted-tests: ${{ steps.matrix.outputs.targeted-tests }} hello-theme-version-for-display: ${{ steps.matrix.outputs.hello-theme-version-for-display }} steps: + - name: Test Slack notification + continue-on-error: true + env: + SLACK_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + run: | + node << 'NODE_SCRIPT' + const slackToken = process.env.SLACK_TOKEN || ''; + + const payload = { + channel: 'C081F86TPFS', + text: 'Test by Hein: Slack notification iniside the Daily Test Matrix is working for the Hello Theme', + blocks: [ + { + type: 'section', + text: { + type: 'mrkdwn', + text: 'Test by Hein: Slack notification iniside the Daily Test Matrix is working for the Hello Theme' + } + } + ] + }; + + const https = require('https'); + const payloadStr = JSON.stringify(payload); + const data = Buffer.from(payloadStr, 'utf8'); + + const options = { + hostname: 'slack.com', + port: 443, + path: '/api/chat.postMessage', + method: 'POST', + headers: { + 'Authorization': `Bearer ${slackToken}`, + 'Content-Type': 'application/json', + 'Content-Length': data.length + } + }; + + const req = https.request(options, (res) => { + let responseData = ''; + res.on('data', (chunk) => { + responseData += chunk; + }); + res.on('end', () => { + if (res.statusCode === 200) { + const response = JSON.parse(responseData); + if (response.ok) { + console.log('✅ Test Slack notification sent successfully'); + } else { + console.error('Slack API error:', response.error); + } + } else { + console.error(`Slack API returned status ${res.statusCode}`); + } + process.exit(0); + }); + }); + + req.on('error', (error) => { + console.error('Request error:', error.message); + process.exit(0); + }); + + req.write(data); + req.end(); + NODE_SCRIPT + - name: Calculate version matrix id: matrix run: | @@ -728,3 +795,185 @@ jobs: } else { console.log(`✅ Daily test matrix completed successfully: ${summary.success} passed out of ${summary.total} tests`); } + + - name: Send Slack notification on failure + if: failure() + continue-on-error: true + env: + WORKFLOW_DATA: ${{ needs.collect-matrix-results.outputs.all-workflow-data }} + TEST_SUMMARY: ${{ steps.aggregate-status.outputs.test-summary }} + OVERALL_STATUS: ${{ steps.aggregate-status.outputs.overall-status }} + TARGETED_TESTS: ${{ needs.calculate-test-matrix.outputs.targeted-tests }} + WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + ACTOR: ${{ github.actor }} + EVENT_NAME: ${{ github.event_name }} + SLACK_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + run: | + if [ -z "$WORKFLOW_DATA" ] || [ "$WORKFLOW_DATA" == "null" ] || [ "$WORKFLOW_DATA" == "" ]; then + exit 0 + fi + + export WORKFLOW_DATA TEST_SUMMARY OVERALL_STATUS TARGETED_TESTS WORKFLOW_URL ACTOR EVENT_NAME SLACK_TOKEN + + node << 'NODE_SCRIPT' + const workflowData = JSON.parse(process.env.WORKFLOW_DATA || '[]'); + const testSummary = JSON.parse(process.env.TEST_SUMMARY || '{}'); + const overallStatus = process.env.OVERALL_STATUS || 'unknown'; + const targetedTests = process.env.TARGETED_TESTS || '[]'; + const workflowUrl = process.env.WORKFLOW_URL || ''; + const actor = process.env.ACTOR || 'unknown'; + const eventName = process.env.EVENT_NAME || 'unknown'; + const slackToken = process.env.SLACK_TOKEN || ''; + + const total = testSummary.total || 0; + const failed = testSummary.failed || 0; + const success = testSummary.success || 0; + const cancelled = testSummary.cancelled || 0; + const inProgress = testSummary.in_progress || 0; + + let matrixSize = 0; + try { + const targetedTestsArray = JSON.parse(targetedTests); + matrixSize = Array.isArray(targetedTestsArray) ? targetedTestsArray.length : 0; + } catch (error) { + matrixSize = 0; + } + + const hasStatusData = workflowData.length > 0 && workflowData.some(r => r.status !== undefined); + const error = hasStatusData ? workflowData.filter(r => r.status === 'error').length : 0; + + if (overallStatus !== 'failure' && failed === 0 && error === 0) { + process.exit(0); + } + + const fields = [ + { + type: 'mrkdwn', + text: `*Total Tests:*\n${total}` + } + ]; + + if (matrixSize > 0) { + fields.push({ + type: 'mrkdwn', + text: `*Matrix Size:*\n${matrixSize}` + }); + } + + if (hasStatusData) { + fields.push( + { + type: 'mrkdwn', + text: `*✅ Success:*\n${success}` + }, + { + type: 'mrkdwn', + text: `*❌ Failed:*\n${failed}` + } + ); + + if (error > 0) { + fields.push({ + type: 'mrkdwn', + text: `*⚠️ Errors:*\n${error}` + }); + } + + if (cancelled > 0) { + fields.push({ + type: 'mrkdwn', + text: `*🚫 Cancelled:*\n${cancelled}` + }); + } + + if (inProgress > 0) { + fields.push({ + type: 'mrkdwn', + text: `*⏳ In Progress:*\n${inProgress}` + }); + } + } else { + fields.push({ + type: 'mrkdwn', + text: `*Status:*\nPending (workflow in progress)` + }); + } + + const failureText = hasStatusData && failed > 0 + ? `${failed} test(s) failed` + : 'Test failures detected'; + + const payload = { + channel: 'C081F86TPFS', + text: `Hello Theme Daily Test Matrix: ${failureText}`, + blocks: [ + { + type: 'section', + text: { + type: 'mrkdwn', + text: `*❌ Hello Theme Daily Test Matrix Failed*\n\n<${workflowUrl}|View Workflow Run>` + } + }, + { + type: 'divider' + }, + { + type: 'section', + fields: fields + }, + { + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: `Triggered by: ${actor} | Event: ${eventName}` + } + ] + } + ] + }; + + const https = require('https'); + const payloadStr = JSON.stringify(payload); + const data = Buffer.from(payloadStr, 'utf8'); + + const options = { + hostname: 'slack.com', + port: 443, + path: '/api/chat.postMessage', + method: 'POST', + headers: { + 'Authorization': `Bearer ${slackToken}`, + 'Content-Type': 'application/json', + 'Content-Length': data.length + } + }; + + const req = https.request(options, (res) => { + let responseData = ''; + res.on('data', (chunk) => { + responseData += chunk; + }); + res.on('end', () => { + if (res.statusCode === 200) { + const response = JSON.parse(responseData); + if (response.ok) { + console.log('✅ Slack notification sent'); + } else { + console.error('Slack API error:', response.error); + } + } else { + console.error(`Slack API returned status ${res.statusCode}`); + } + process.exit(0); + }); + }); + + req.on('error', (error) => { + console.error('Request error:', error.message); + process.exit(0); + }); + + req.write(data); + req.end(); + NODE_SCRIPT From 8256972e082b25b375cf1cafae40ee59169d7ea3 Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin Date: Wed, 26 Nov 2025 09:40:45 +0200 Subject: [PATCH 02/16] debug --- .github/workflows/daily-test-matrix.yml | 67 +++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/.github/workflows/daily-test-matrix.yml b/.github/workflows/daily-test-matrix.yml index fc581c4c..51cf5577 100644 --- a/.github/workflows/daily-test-matrix.yml +++ b/.github/workflows/daily-test-matrix.yml @@ -92,10 +92,33 @@ jobs: - name: Test Slack notification continue-on-error: true env: - SLACK_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + SLACK_TOKEN: ${{ secrets.SLACK_BOT_TOKEN || secrets.CLOUD_SLACK_BOT_TOKEN }} + SLACK_TOKEN_SOURCE: ${{ secrets.SLACK_BOT_TOKEN && 'SLACK_BOT_TOKEN' || (secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || 'none') }} run: | + echo "🔍 Debugging Slack notification..." + echo "Token source: $SLACK_TOKEN_SOURCE" + echo "Token present: $([ -n "$SLACK_TOKEN" ] && echo 'yes' || echo 'no')" + echo "Token length: ${#SLACK_TOKEN}" + echo "Token starts with: ${SLACK_TOKEN:0:10}..." + node << 'NODE_SCRIPT' const slackToken = process.env.SLACK_TOKEN || ''; + const tokenSource = process.env.SLACK_TOKEN_SOURCE || 'unknown'; + + console.log('🔍 Debug Information:'); + console.log(`Token source: ${tokenSource}`); + console.log(`Token present: ${slackToken ? 'yes' : 'no'}`); + console.log(`Token length: ${slackToken.length}`); + console.log(`Token starts with: ${slackToken.substring(0, 10)}...`); + console.log(`Token format check: ${slackToken.startsWith('xoxb-') ? 'Bot token format ✓' : 'Not a bot token format (should start with xoxb-)'}`); + + if (!slackToken) { + console.error('❌ SLACK_TOKEN is empty or not set'); + console.error('Please check that one of these secrets is configured in repository settings:'); + console.error(' - secrets.SLACK_BOT_TOKEN (used by Hello Theme release workflow)'); + console.error(' - secrets.CLOUD_SLACK_BOT_TOKEN (used by Hello Plus workflows)'); + process.exit(0); + } const payload = { channel: 'C081F86TPFS', @@ -115,6 +138,10 @@ jobs: const payloadStr = JSON.stringify(payload); const data = Buffer.from(payloadStr, 'utf8'); + console.log('📤 Sending request to Slack API...'); + console.log(`Channel: C081F86TPFS`); + console.log(`Payload size: ${data.length} bytes`); + const options = { hostname: 'slack.com', port: 443, @@ -133,22 +160,41 @@ jobs: responseData += chunk; }); res.on('end', () => { + console.log(`📥 Response status: ${res.statusCode}`); + console.log(`📥 Response headers:`, JSON.stringify(res.headers, null, 2)); + if (res.statusCode === 200) { const response = JSON.parse(responseData); + console.log(`📥 Full response:`, JSON.stringify(response, null, 2)); + if (response.ok) { console.log('✅ Test Slack notification sent successfully'); } else { - console.error('Slack API error:', response.error); + console.error('❌ Slack API error:', response.error); + if (response.error === 'not_authed') { + console.error('💡 This usually means:'); + console.error(' 1. The token is invalid or expired'); + console.error(' 2. The token does not have the required scopes (chat:write)'); + console.error(` 3. The secret ${tokenSource} is not set or incorrect in repository settings`); + console.error(' 4. The bot needs to be invited to the channel C081F86TPFS'); + } } } else { - console.error(`Slack API returned status ${res.statusCode}`); + console.error(`❌ Slack API returned status ${res.statusCode}`); + try { + const errorResponse = JSON.parse(responseData); + console.error(`📥 Error response:`, JSON.stringify(errorResponse, null, 2)); + } catch (e) { + console.error(`📥 Raw response:`, responseData); + } } process.exit(0); }); }); req.on('error', (error) => { - console.error('Request error:', error.message); + console.error('❌ Request error:', error.message); + console.error('Stack:', error.stack); process.exit(0); }); @@ -807,7 +853,8 @@ jobs: WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} ACTOR: ${{ github.actor }} EVENT_NAME: ${{ github.event_name }} - SLACK_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + SLACK_TOKEN: ${{ secrets.SLACK_BOT_TOKEN || secrets.CLOUD_SLACK_BOT_TOKEN }} + SLACK_TOKEN_SOURCE: ${{ secrets.SLACK_BOT_TOKEN && 'SLACK_BOT_TOKEN' || (secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || 'none') }} run: | if [ -z "$WORKFLOW_DATA" ] || [ "$WORKFLOW_DATA" == "null" ] || [ "$WORKFLOW_DATA" == "" ]; then exit 0 @@ -824,6 +871,16 @@ jobs: const actor = process.env.ACTOR || 'unknown'; const eventName = process.env.EVENT_NAME || 'unknown'; const slackToken = process.env.SLACK_TOKEN || ''; + const tokenSource = process.env.SLACK_TOKEN_SOURCE || 'unknown'; + + if (!slackToken) { + console.error('❌ SLACK_TOKEN is empty or not set'); + console.error(`Token source: ${tokenSource}`); + console.error('Please check that one of these secrets is configured in repository settings:'); + console.error(' - secrets.SLACK_BOT_TOKEN (used by Hello Theme release workflow)'); + console.error(' - secrets.CLOUD_SLACK_BOT_TOKEN (used by Hello Plus workflows)'); + process.exit(0); + } const total = testSummary.total || 0; const failed = testSummary.failed || 0; From 183cc4fa68ad898d5a73ad568c107fc94696bce3 Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin Date: Wed, 26 Nov 2025 09:44:00 +0200 Subject: [PATCH 03/16] wip --- .github/workflows/daily-test-matrix.yml | 28 ++++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/.github/workflows/daily-test-matrix.yml b/.github/workflows/daily-test-matrix.yml index 51cf5577..f7da6b60 100644 --- a/.github/workflows/daily-test-matrix.yml +++ b/.github/workflows/daily-test-matrix.yml @@ -92,8 +92,8 @@ jobs: - name: Test Slack notification continue-on-error: true env: - SLACK_TOKEN: ${{ secrets.SLACK_BOT_TOKEN || secrets.CLOUD_SLACK_BOT_TOKEN }} - SLACK_TOKEN_SOURCE: ${{ secrets.SLACK_BOT_TOKEN && 'SLACK_BOT_TOKEN' || (secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || 'none') }} + SLACK_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN || secrets.SLACK_BOT_TOKEN }} + SLACK_TOKEN_SOURCE: ${{ secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || (secrets.SLACK_BOT_TOKEN && 'SLACK_BOT_TOKEN' || 'none') }} run: | echo "🔍 Debugging Slack notification..." echo "Token source: $SLACK_TOKEN_SOURCE" @@ -114,9 +114,13 @@ jobs: if (!slackToken) { console.error('❌ SLACK_TOKEN is empty or not set'); - console.error('Please check that one of these secrets is configured in repository settings:'); - console.error(' - secrets.SLACK_BOT_TOKEN (used by Hello Theme release workflow)'); - console.error(' - secrets.CLOUD_SLACK_BOT_TOKEN (used by Hello Plus workflows)'); + console.error('Please check that one of these secrets is configured:'); + console.error(' - secrets.CLOUD_SLACK_BOT_TOKEN (organization secret, preferred - used by Hello Plus workflows)'); + console.error(' - secrets.SLACK_BOT_TOKEN (repository secret - used by Hello Theme release workflow)'); + console.error(''); + console.error('For organization secrets:'); + console.error(' 1. Go to organization settings > Secrets and variables > Actions'); + console.error(' 2. Ensure CLOUD_SLACK_BOT_TOKEN is available to this repository'); process.exit(0); } @@ -853,8 +857,8 @@ jobs: WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} ACTOR: ${{ github.actor }} EVENT_NAME: ${{ github.event_name }} - SLACK_TOKEN: ${{ secrets.SLACK_BOT_TOKEN || secrets.CLOUD_SLACK_BOT_TOKEN }} - SLACK_TOKEN_SOURCE: ${{ secrets.SLACK_BOT_TOKEN && 'SLACK_BOT_TOKEN' || (secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || 'none') }} + SLACK_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN || secrets.SLACK_BOT_TOKEN }} + SLACK_TOKEN_SOURCE: ${{ secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || (secrets.SLACK_BOT_TOKEN && 'SLACK_BOT_TOKEN' || 'none') }} run: | if [ -z "$WORKFLOW_DATA" ] || [ "$WORKFLOW_DATA" == "null" ] || [ "$WORKFLOW_DATA" == "" ]; then exit 0 @@ -876,9 +880,13 @@ jobs: if (!slackToken) { console.error('❌ SLACK_TOKEN is empty or not set'); console.error(`Token source: ${tokenSource}`); - console.error('Please check that one of these secrets is configured in repository settings:'); - console.error(' - secrets.SLACK_BOT_TOKEN (used by Hello Theme release workflow)'); - console.error(' - secrets.CLOUD_SLACK_BOT_TOKEN (used by Hello Plus workflows)'); + console.error('Please check that one of these secrets is configured:'); + console.error(' - secrets.CLOUD_SLACK_BOT_TOKEN (organization secret, preferred - used by Hello Plus workflows)'); + console.error(' - secrets.SLACK_BOT_TOKEN (repository secret - used by Hello Theme release workflow)'); + console.error(''); + console.error('For organization secrets:'); + console.error(' 1. Go to organization settings > Secrets and variables > Actions'); + console.error(' 2. Ensure CLOUD_SLACK_BOT_TOKEN is available to this repository'); process.exit(0); } From 7ba34dfe1b4dc584713d9ac99214a4f9e2bdae48 Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin Date: Wed, 26 Nov 2025 09:46:31 +0200 Subject: [PATCH 04/16] wip --- .github/workflows/daily-test-matrix.yml | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/daily-test-matrix.yml b/.github/workflows/daily-test-matrix.yml index f7da6b60..8b77faec 100644 --- a/.github/workflows/daily-test-matrix.yml +++ b/.github/workflows/daily-test-matrix.yml @@ -92,8 +92,8 @@ jobs: - name: Test Slack notification continue-on-error: true env: - SLACK_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN || secrets.SLACK_BOT_TOKEN }} - SLACK_TOKEN_SOURCE: ${{ secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || (secrets.SLACK_BOT_TOKEN && 'SLACK_BOT_TOKEN' || 'none') }} + SLACK_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN }} + SLACK_TOKEN_SOURCE: ${{ secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || 'none' }} run: | echo "🔍 Debugging Slack notification..." echo "Token source: $SLACK_TOKEN_SOURCE" @@ -114,13 +114,11 @@ jobs: if (!slackToken) { console.error('❌ SLACK_TOKEN is empty or not set'); - console.error('Please check that one of these secrets is configured:'); - console.error(' - secrets.CLOUD_SLACK_BOT_TOKEN (organization secret, preferred - used by Hello Plus workflows)'); - console.error(' - secrets.SLACK_BOT_TOKEN (repository secret - used by Hello Theme release workflow)'); + console.error('Please check that secrets.CLOUD_SLACK_BOT_TOKEN is configured:'); console.error(''); console.error('For organization secrets:'); console.error(' 1. Go to organization settings > Secrets and variables > Actions'); - console.error(' 2. Ensure CLOUD_SLACK_BOT_TOKEN is available to this repository'); + console.error(' 2. Ensure CLOUD_SLACK_BOT_TOKEN exists and is available to this repository'); process.exit(0); } @@ -857,8 +855,8 @@ jobs: WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} ACTOR: ${{ github.actor }} EVENT_NAME: ${{ github.event_name }} - SLACK_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN || secrets.SLACK_BOT_TOKEN }} - SLACK_TOKEN_SOURCE: ${{ secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || (secrets.SLACK_BOT_TOKEN && 'SLACK_BOT_TOKEN' || 'none') }} + SLACK_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN }} + SLACK_TOKEN_SOURCE: ${{ secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || 'none' }} run: | if [ -z "$WORKFLOW_DATA" ] || [ "$WORKFLOW_DATA" == "null" ] || [ "$WORKFLOW_DATA" == "" ]; then exit 0 @@ -880,13 +878,11 @@ jobs: if (!slackToken) { console.error('❌ SLACK_TOKEN is empty or not set'); console.error(`Token source: ${tokenSource}`); - console.error('Please check that one of these secrets is configured:'); - console.error(' - secrets.CLOUD_SLACK_BOT_TOKEN (organization secret, preferred - used by Hello Plus workflows)'); - console.error(' - secrets.SLACK_BOT_TOKEN (repository secret - used by Hello Theme release workflow)'); + console.error('Please check that secrets.CLOUD_SLACK_BOT_TOKEN is configured:'); console.error(''); console.error('For organization secrets:'); console.error(' 1. Go to organization settings > Secrets and variables > Actions'); - console.error(' 2. Ensure CLOUD_SLACK_BOT_TOKEN is available to this repository'); + console.error(' 2. Ensure CLOUD_SLACK_BOT_TOKEN exists and is available to this repository'); process.exit(0); } From 5a47ce055f0e4b672b75d0413351f564a66e6ebb Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin Date: Wed, 26 Nov 2025 09:49:56 +0200 Subject: [PATCH 05/16] wip --- .github/workflows/daily-test-matrix.yml | 30 ++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/daily-test-matrix.yml b/.github/workflows/daily-test-matrix.yml index 8b77faec..1afd082e 100644 --- a/.github/workflows/daily-test-matrix.yml +++ b/.github/workflows/daily-test-matrix.yml @@ -92,18 +92,18 @@ jobs: - name: Test Slack notification continue-on-error: true env: - SLACK_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN }} - SLACK_TOKEN_SOURCE: ${{ secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || 'none' }} + CLOUD_SLACK_BOT_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN }} + CLOUD_SLACK_BOT_TOKEN_SOURCE: ${{ secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || 'none' }} run: | echo "🔍 Debugging Slack notification..." - echo "Token source: $SLACK_TOKEN_SOURCE" - echo "Token present: $([ -n "$SLACK_TOKEN" ] && echo 'yes' || echo 'no')" - echo "Token length: ${#SLACK_TOKEN}" - echo "Token starts with: ${SLACK_TOKEN:0:10}..." + echo "Token source: $CLOUD_SLACK_BOT_TOKEN_SOURCE" + echo "Token present: $([ -n "$CLOUD_SLACK_BOT_TOKEN" ] && echo 'yes' || echo 'no')" + echo "Token length: ${#CLOUD_SLACK_BOT_TOKEN}" + echo "Token starts with: ${CLOUD_SLACK_BOT_TOKEN:0:10}..." node << 'NODE_SCRIPT' - const slackToken = process.env.SLACK_TOKEN || ''; - const tokenSource = process.env.SLACK_TOKEN_SOURCE || 'unknown'; + const slackToken = process.env.CLOUD_SLACK_BOT_TOKEN || ''; + const tokenSource = process.env.CLOUD_SLACK_BOT_TOKEN_SOURCE || 'unknown'; console.log('🔍 Debug Information:'); console.log(`Token source: ${tokenSource}`); @@ -113,7 +113,7 @@ jobs: console.log(`Token format check: ${slackToken.startsWith('xoxb-') ? 'Bot token format ✓' : 'Not a bot token format (should start with xoxb-)'}`); if (!slackToken) { - console.error('❌ SLACK_TOKEN is empty or not set'); + console.error('❌ CLOUD_SLACK_BOT_TOKEN is empty or not set'); console.error('Please check that secrets.CLOUD_SLACK_BOT_TOKEN is configured:'); console.error(''); console.error('For organization secrets:'); @@ -855,14 +855,14 @@ jobs: WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} ACTOR: ${{ github.actor }} EVENT_NAME: ${{ github.event_name }} - SLACK_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN }} - SLACK_TOKEN_SOURCE: ${{ secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || 'none' }} + CLOUD_SLACK_BOT_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN }} + CLOUD_SLACK_BOT_TOKEN_SOURCE: ${{ secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || 'none' }} run: | if [ -z "$WORKFLOW_DATA" ] || [ "$WORKFLOW_DATA" == "null" ] || [ "$WORKFLOW_DATA" == "" ]; then exit 0 fi - export WORKFLOW_DATA TEST_SUMMARY OVERALL_STATUS TARGETED_TESTS WORKFLOW_URL ACTOR EVENT_NAME SLACK_TOKEN + export WORKFLOW_DATA TEST_SUMMARY OVERALL_STATUS TARGETED_TESTS WORKFLOW_URL ACTOR EVENT_NAME CLOUD_SLACK_BOT_TOKEN node << 'NODE_SCRIPT' const workflowData = JSON.parse(process.env.WORKFLOW_DATA || '[]'); @@ -872,11 +872,11 @@ jobs: const workflowUrl = process.env.WORKFLOW_URL || ''; const actor = process.env.ACTOR || 'unknown'; const eventName = process.env.EVENT_NAME || 'unknown'; - const slackToken = process.env.SLACK_TOKEN || ''; - const tokenSource = process.env.SLACK_TOKEN_SOURCE || 'unknown'; + const slackToken = process.env.CLOUD_SLACK_BOT_TOKEN || ''; + const tokenSource = process.env.CLOUD_SLACK_BOT_TOKEN_SOURCE || 'unknown'; if (!slackToken) { - console.error('❌ SLACK_TOKEN is empty or not set'); + console.error('❌ CLOUD_SLACK_BOT_TOKEN is empty or not set'); console.error(`Token source: ${tokenSource}`); console.error('Please check that secrets.CLOUD_SLACK_BOT_TOKEN is configured:'); console.error(''); From ca7a2ec5b14d5fd6884b7f669dceb1d8879e8b1b Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin Date: Wed, 26 Nov 2025 09:56:08 +0200 Subject: [PATCH 06/16] Update channel name. --- .github/workflows/daily-test-matrix.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/daily-test-matrix.yml b/.github/workflows/daily-test-matrix.yml index 1afd082e..c40e1688 100644 --- a/.github/workflows/daily-test-matrix.yml +++ b/.github/workflows/daily-test-matrix.yml @@ -123,7 +123,7 @@ jobs: } const payload = { - channel: 'C081F86TPFS', + channel: '#tmz-alerts', text: 'Test by Hein: Slack notification iniside the Daily Test Matrix is working for the Hello Theme', blocks: [ { @@ -141,7 +141,7 @@ jobs: const data = Buffer.from(payloadStr, 'utf8'); console.log('📤 Sending request to Slack API...'); - console.log(`Channel: C081F86TPFS`); + console.log(`Channel: #tmz-alerts`); console.log(`Payload size: ${data.length} bytes`); const options = { @@ -178,7 +178,7 @@ jobs: console.error(' 1. The token is invalid or expired'); console.error(' 2. The token does not have the required scopes (chat:write)'); console.error(` 3. The secret ${tokenSource} is not set or incorrect in repository settings`); - console.error(' 4. The bot needs to be invited to the channel C081F86TPFS'); + console.error(' 4. The bot needs to be invited to the channel #tmz-alerts'); } } } else { @@ -965,7 +965,7 @@ jobs: : 'Test failures detected'; const payload = { - channel: 'C081F86TPFS', + channel: '#tmz-alerts', text: `Hello Theme Daily Test Matrix: ${failureText}`, blocks: [ { From 7313fb25e098059edab2426c2f3689ba0075c997 Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin Date: Wed, 26 Nov 2025 10:01:50 +0200 Subject: [PATCH 07/16] Clean up initial test notification --- .github/workflows/daily-test-matrix.yml | 115 ------------------------ 1 file changed, 115 deletions(-) diff --git a/.github/workflows/daily-test-matrix.yml b/.github/workflows/daily-test-matrix.yml index c40e1688..23e8a351 100644 --- a/.github/workflows/daily-test-matrix.yml +++ b/.github/workflows/daily-test-matrix.yml @@ -89,121 +89,6 @@ jobs: targeted-tests: ${{ steps.matrix.outputs.targeted-tests }} hello-theme-version-for-display: ${{ steps.matrix.outputs.hello-theme-version-for-display }} steps: - - name: Test Slack notification - continue-on-error: true - env: - CLOUD_SLACK_BOT_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN }} - CLOUD_SLACK_BOT_TOKEN_SOURCE: ${{ secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || 'none' }} - run: | - echo "🔍 Debugging Slack notification..." - echo "Token source: $CLOUD_SLACK_BOT_TOKEN_SOURCE" - echo "Token present: $([ -n "$CLOUD_SLACK_BOT_TOKEN" ] && echo 'yes' || echo 'no')" - echo "Token length: ${#CLOUD_SLACK_BOT_TOKEN}" - echo "Token starts with: ${CLOUD_SLACK_BOT_TOKEN:0:10}..." - - node << 'NODE_SCRIPT' - const slackToken = process.env.CLOUD_SLACK_BOT_TOKEN || ''; - const tokenSource = process.env.CLOUD_SLACK_BOT_TOKEN_SOURCE || 'unknown'; - - console.log('🔍 Debug Information:'); - console.log(`Token source: ${tokenSource}`); - console.log(`Token present: ${slackToken ? 'yes' : 'no'}`); - console.log(`Token length: ${slackToken.length}`); - console.log(`Token starts with: ${slackToken.substring(0, 10)}...`); - console.log(`Token format check: ${slackToken.startsWith('xoxb-') ? 'Bot token format ✓' : 'Not a bot token format (should start with xoxb-)'}`); - - if (!slackToken) { - console.error('❌ CLOUD_SLACK_BOT_TOKEN is empty or not set'); - console.error('Please check that secrets.CLOUD_SLACK_BOT_TOKEN is configured:'); - console.error(''); - console.error('For organization secrets:'); - console.error(' 1. Go to organization settings > Secrets and variables > Actions'); - console.error(' 2. Ensure CLOUD_SLACK_BOT_TOKEN exists and is available to this repository'); - process.exit(0); - } - - const payload = { - channel: '#tmz-alerts', - text: 'Test by Hein: Slack notification iniside the Daily Test Matrix is working for the Hello Theme', - blocks: [ - { - type: 'section', - text: { - type: 'mrkdwn', - text: 'Test by Hein: Slack notification iniside the Daily Test Matrix is working for the Hello Theme' - } - } - ] - }; - - const https = require('https'); - const payloadStr = JSON.stringify(payload); - const data = Buffer.from(payloadStr, 'utf8'); - - console.log('📤 Sending request to Slack API...'); - console.log(`Channel: #tmz-alerts`); - console.log(`Payload size: ${data.length} bytes`); - - const options = { - hostname: 'slack.com', - port: 443, - path: '/api/chat.postMessage', - method: 'POST', - headers: { - 'Authorization': `Bearer ${slackToken}`, - 'Content-Type': 'application/json', - 'Content-Length': data.length - } - }; - - const req = https.request(options, (res) => { - let responseData = ''; - res.on('data', (chunk) => { - responseData += chunk; - }); - res.on('end', () => { - console.log(`📥 Response status: ${res.statusCode}`); - console.log(`📥 Response headers:`, JSON.stringify(res.headers, null, 2)); - - if (res.statusCode === 200) { - const response = JSON.parse(responseData); - console.log(`📥 Full response:`, JSON.stringify(response, null, 2)); - - if (response.ok) { - console.log('✅ Test Slack notification sent successfully'); - } else { - console.error('❌ Slack API error:', response.error); - if (response.error === 'not_authed') { - console.error('💡 This usually means:'); - console.error(' 1. The token is invalid or expired'); - console.error(' 2. The token does not have the required scopes (chat:write)'); - console.error(` 3. The secret ${tokenSource} is not set or incorrect in repository settings`); - console.error(' 4. The bot needs to be invited to the channel #tmz-alerts'); - } - } - } else { - console.error(`❌ Slack API returned status ${res.statusCode}`); - try { - const errorResponse = JSON.parse(responseData); - console.error(`📥 Error response:`, JSON.stringify(errorResponse, null, 2)); - } catch (e) { - console.error(`📥 Raw response:`, responseData); - } - } - process.exit(0); - }); - }); - - req.on('error', (error) => { - console.error('❌ Request error:', error.message); - console.error('Stack:', error.stack); - process.exit(0); - }); - - req.write(data); - req.end(); - NODE_SCRIPT - - name: Calculate version matrix id: matrix run: | From 6290548544afe176bacd7b23fbe59e73a7e322e8 Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin Date: Wed, 26 Nov 2025 10:21:41 +0200 Subject: [PATCH 08/16] Refactor --- .../action.yml | 58 ++++++ .../action.yml | 153 ++++++++------ .github/scripts/send-slack-message.js | 63 ++++++ .github/workflows/daily-test-matrix.yml | 194 +----------------- .github/workflows/release.yml | 2 +- 5 files changed, 214 insertions(+), 256 deletions(-) create mode 100644 .github/actions/theme-slack-notification-daily-tests/action.yml create mode 100644 .github/scripts/send-slack-message.js diff --git a/.github/actions/theme-slack-notification-daily-tests/action.yml b/.github/actions/theme-slack-notification-daily-tests/action.yml new file mode 100644 index 00000000..af94ebf8 --- /dev/null +++ b/.github/actions/theme-slack-notification-daily-tests/action.yml @@ -0,0 +1,58 @@ +name: 'Theme Slack Notification (Daily Tests)' +description: 'Send Slack notification for Hello Elementor daily test failures' +inputs: + CLOUD_SLACK_BOT_TOKEN: + required: true + description: 'Slack bot token' + WORKFLOW_URL: + required: true + description: 'GitHub workflow run URL' + SLACK_CHANNEL: + required: false + default: '#tmz-hello-delivery' + description: 'Slack channel to send notification to' + +runs: + using: 'composite' + steps: + - name: Post to Slack + shell: bash + env: + CLOUD_SLACK_BOT_TOKEN: ${{ inputs.CLOUD_SLACK_BOT_TOKEN }} + WORKFLOW_URL: ${{ inputs.WORKFLOW_URL }} + SLACK_CHANNEL: ${{ inputs.SLACK_CHANNEL }} + run: | + export CLOUD_SLACK_BOT_TOKEN WORKFLOW_URL SLACK_CHANNEL + + node << 'NODE_SCRIPT' + const workflowUrl = process.env.WORKFLOW_URL || ''; + const slackChannel = process.env.SLACK_CHANNEL || '#tmz-hello-delivery'; + + const payload = { + text: 'Failing test alert', + blocks: [ + { + type: 'section', + text: { + type: 'mrkdwn', + text: '*Failing test alert*\n\n*Theme:* Hello Elementor\n*Test report:* <' + workflowUrl + '|View Workflow Run>' + } + } + ] + }; + + process.env.SLACK_PAYLOAD = JSON.stringify(payload); + + const { execSync } = require('child_process'); + const path = require('path'); + const scriptPath = path.join(process.env.GITHUB_WORKSPACE, '.github/scripts/send-slack-message.js'); + execSync(`node "${scriptPath}"`, { stdio: 'inherit', env: process.env }); + NODE_SCRIPT + + - name: Notification summary + shell: bash + run: | + echo "📢 Slack notification sent!" + echo " - Channel: ${{ inputs.SLACK_CHANNEL }}" + echo " - Workflow: ${{ inputs.WORKFLOW_URL }}" + diff --git a/.github/actions/theme-slack-notification-release/action.yml b/.github/actions/theme-slack-notification-release/action.yml index a599ccbf..e1ba137f 100644 --- a/.github/actions/theme-slack-notification-release/action.yml +++ b/.github/actions/theme-slack-notification-release/action.yml @@ -1,7 +1,7 @@ name: 'Theme Slack Notification (Release)' description: 'Send Slack notification for Hello Elementor release' inputs: - SLACK_BOT_TOKEN: + CLOUD_SLACK_BOT_TOKEN: required: true description: 'Slack bot token' PACKAGE_VERSION: @@ -56,73 +56,96 @@ runs: fi - name: Post to Slack - uses: slackapi/slack-github-action@v1.23.0 - with: - channel-id: ${{ inputs.SLACK_CHANNEL }} - payload: | - { - "blocks": [ - { - "type": "header", - "text": { - "type": "plain_text", - "text": "🚀 Hello Elementor v${{ inputs.PACKAGE_VERSION }} Released!" - } - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "*Hello Elementor theme* has been successfully released and is ready for distribution." + shell: bash + env: + CLOUD_SLACK_BOT_TOKEN: ${{ inputs.CLOUD_SLACK_BOT_TOKEN }} + SLACK_CHANNEL: ${{ inputs.SLACK_CHANNEL }} + PACKAGE_VERSION: ${{ inputs.PACKAGE_VERSION }} + FILE_SIZE_MB: ${{ env.FILE_SIZE_MB }} + DEPLOYMENT_MESSAGE: ${{ env.DEPLOYMENT_MESSAGE }} + GITHUB_RELEASE_URL: ${{ inputs.GITHUB_RELEASE_URL }} + BUILD_ZIP_PATH: ${{ inputs.BUILD_ZIP_PATH }} + run: | + export CLOUD_SLACK_BOT_TOKEN SLACK_CHANNEL PACKAGE_VERSION FILE_SIZE_MB DEPLOYMENT_MESSAGE GITHUB_RELEASE_URL BUILD_ZIP_PATH + + node << 'NODE_SCRIPT' + const slackChannel = process.env.SLACK_CHANNEL || '#general'; + const packageVersion = process.env.PACKAGE_VERSION || ''; + const fileSizeMb = process.env.FILE_SIZE_MB || 'Unknown'; + const deploymentMessage = (process.env.DEPLOYMENT_MESSAGE || '').replace(/\\n/g, '\n'); + const githubReleaseUrl = process.env.GITHUB_RELEASE_URL || ''; + const buildZipPath = process.env.BUILD_ZIP_PATH || ''; + + const payload = { + text: `Hello Elementor v${packageVersion} Released!`, + blocks: [ + { + type: 'header', + text: { + type: 'plain_text', + text: `🚀 Hello Elementor v${packageVersion} Released!` + } + }, + { + type: 'section', + text: { + type: 'mrkdwn', + text: '*Hello Elementor theme* has been successfully released and is ready for distribution.' + } + }, + { + type: 'section', + fields: [ + { + type: 'mrkdwn', + text: `*Version:*\nv${packageVersion}` + }, + { + type: 'mrkdwn', + text: `*Package Size:*\n${fileSizeMb}` } - }, - { - "type": "section", - "fields": [ - { - "type": "mrkdwn", - "text": "*Version:*\nv${{ inputs.PACKAGE_VERSION }}" + ] + }, + { + type: 'section', + text: { + type: 'mrkdwn', + text: deploymentMessage + } + }, + { + type: 'actions', + elements: [ + { + type: 'button', + text: { + type: 'plain_text', + text: '📥 Download Release' }, - { - "type": "mrkdwn", - "text": "*Package Size:*\n${{ env.FILE_SIZE_MB }}" - } - ] - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "${{ env.DEPLOYMENT_MESSAGE }}" + url: githubReleaseUrl, + style: 'primary' } - }, - { - "type": "actions", - "elements": [ - { - "type": "button", - "text": { - "type": "plain_text", - "text": "📥 Download Release" - }, - "url": "${{ inputs.GITHUB_RELEASE_URL }}", - "style": "primary" - } - ] - }, - { - "type": "context", - "elements": [ - { - "type": "mrkdwn", - "text": "Build: ${{ inputs.BUILD_ZIP_PATH }}" - } - ] - } - ] - } - env: - SLACK_BOT_TOKEN: ${{ inputs.SLACK_BOT_TOKEN }} + ] + }, + { + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: `Build: ${buildZipPath}` + } + ] + } + ] + }; + + process.env.SLACK_PAYLOAD = JSON.stringify(payload); + + const { execSync } = require('child_process'); + const path = require('path'); + const scriptPath = path.join(process.env.GITHUB_WORKSPACE, '.github/scripts/send-slack-message.js'); + execSync(`node "${scriptPath}"`, { stdio: 'inherit', env: process.env }); + NODE_SCRIPT - name: Notification summary shell: bash diff --git a/.github/scripts/send-slack-message.js b/.github/scripts/send-slack-message.js new file mode 100644 index 00000000..fb971858 --- /dev/null +++ b/.github/scripts/send-slack-message.js @@ -0,0 +1,63 @@ +const https = require('https'); + +const slackToken = process.env.CLOUD_SLACK_BOT_TOKEN || ''; +const slackChannel = process.env.SLACK_CHANNEL || '#general'; +const payloadJson = process.env.SLACK_PAYLOAD || '{}'; + +if (!slackToken) { + console.log('⚠️ Slack token not provided, skipping notification'); + process.exit(0); +} + +let payload; +try { + payload = JSON.parse(payloadJson); + payload.channel = slackChannel; +} catch (error) { + console.error('Failed to parse payload:', error.message); + process.exit(1); +} + +const payloadStr = JSON.stringify(payload); +const data = Buffer.from(payloadStr, 'utf8'); + +const options = { + hostname: 'slack.com', + port: 443, + path: '/api/chat.postMessage', + method: 'POST', + headers: { + 'Authorization': `Bearer ${slackToken}`, + 'Content-Type': 'application/json', + 'Content-Length': data.length + } +}; + +const req = https.request(options, (res) => { + let responseData = ''; + res.on('data', (chunk) => { + responseData += chunk; + }); + res.on('end', () => { + if (res.statusCode === 200) { + const response = JSON.parse(responseData); + if (response.ok) { + console.log('✅ Slack notification sent'); + } else { + console.error('Slack API error:', response.error); + } + } else { + console.error(`Slack API returned status ${res.statusCode}`); + } + process.exit(0); + }); +}); + +req.on('error', (error) => { + console.error('Request error:', error.message); + process.exit(0); +}); + +req.write(data); +req.end(); + diff --git a/.github/workflows/daily-test-matrix.yml b/.github/workflows/daily-test-matrix.yml index 23e8a351..960cb7db 100644 --- a/.github/workflows/daily-test-matrix.yml +++ b/.github/workflows/daily-test-matrix.yml @@ -732,194 +732,8 @@ jobs: - name: Send Slack notification on failure if: failure() continue-on-error: true - env: - WORKFLOW_DATA: ${{ needs.collect-matrix-results.outputs.all-workflow-data }} - TEST_SUMMARY: ${{ steps.aggregate-status.outputs.test-summary }} - OVERALL_STATUS: ${{ steps.aggregate-status.outputs.overall-status }} - TARGETED_TESTS: ${{ needs.calculate-test-matrix.outputs.targeted-tests }} - WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - ACTOR: ${{ github.actor }} - EVENT_NAME: ${{ github.event_name }} + uses: ./.github/actions/theme-slack-notification-daily-tests + with: CLOUD_SLACK_BOT_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN }} - CLOUD_SLACK_BOT_TOKEN_SOURCE: ${{ secrets.CLOUD_SLACK_BOT_TOKEN && 'CLOUD_SLACK_BOT_TOKEN' || 'none' }} - run: | - if [ -z "$WORKFLOW_DATA" ] || [ "$WORKFLOW_DATA" == "null" ] || [ "$WORKFLOW_DATA" == "" ]; then - exit 0 - fi - - export WORKFLOW_DATA TEST_SUMMARY OVERALL_STATUS TARGETED_TESTS WORKFLOW_URL ACTOR EVENT_NAME CLOUD_SLACK_BOT_TOKEN - - node << 'NODE_SCRIPT' - const workflowData = JSON.parse(process.env.WORKFLOW_DATA || '[]'); - const testSummary = JSON.parse(process.env.TEST_SUMMARY || '{}'); - const overallStatus = process.env.OVERALL_STATUS || 'unknown'; - const targetedTests = process.env.TARGETED_TESTS || '[]'; - const workflowUrl = process.env.WORKFLOW_URL || ''; - const actor = process.env.ACTOR || 'unknown'; - const eventName = process.env.EVENT_NAME || 'unknown'; - const slackToken = process.env.CLOUD_SLACK_BOT_TOKEN || ''; - const tokenSource = process.env.CLOUD_SLACK_BOT_TOKEN_SOURCE || 'unknown'; - - if (!slackToken) { - console.error('❌ CLOUD_SLACK_BOT_TOKEN is empty or not set'); - console.error(`Token source: ${tokenSource}`); - console.error('Please check that secrets.CLOUD_SLACK_BOT_TOKEN is configured:'); - console.error(''); - console.error('For organization secrets:'); - console.error(' 1. Go to organization settings > Secrets and variables > Actions'); - console.error(' 2. Ensure CLOUD_SLACK_BOT_TOKEN exists and is available to this repository'); - process.exit(0); - } - - const total = testSummary.total || 0; - const failed = testSummary.failed || 0; - const success = testSummary.success || 0; - const cancelled = testSummary.cancelled || 0; - const inProgress = testSummary.in_progress || 0; - - let matrixSize = 0; - try { - const targetedTestsArray = JSON.parse(targetedTests); - matrixSize = Array.isArray(targetedTestsArray) ? targetedTestsArray.length : 0; - } catch (error) { - matrixSize = 0; - } - - const hasStatusData = workflowData.length > 0 && workflowData.some(r => r.status !== undefined); - const error = hasStatusData ? workflowData.filter(r => r.status === 'error').length : 0; - - if (overallStatus !== 'failure' && failed === 0 && error === 0) { - process.exit(0); - } - - const fields = [ - { - type: 'mrkdwn', - text: `*Total Tests:*\n${total}` - } - ]; - - if (matrixSize > 0) { - fields.push({ - type: 'mrkdwn', - text: `*Matrix Size:*\n${matrixSize}` - }); - } - - if (hasStatusData) { - fields.push( - { - type: 'mrkdwn', - text: `*✅ Success:*\n${success}` - }, - { - type: 'mrkdwn', - text: `*❌ Failed:*\n${failed}` - } - ); - - if (error > 0) { - fields.push({ - type: 'mrkdwn', - text: `*⚠️ Errors:*\n${error}` - }); - } - - if (cancelled > 0) { - fields.push({ - type: 'mrkdwn', - text: `*🚫 Cancelled:*\n${cancelled}` - }); - } - - if (inProgress > 0) { - fields.push({ - type: 'mrkdwn', - text: `*⏳ In Progress:*\n${inProgress}` - }); - } - } else { - fields.push({ - type: 'mrkdwn', - text: `*Status:*\nPending (workflow in progress)` - }); - } - - const failureText = hasStatusData && failed > 0 - ? `${failed} test(s) failed` - : 'Test failures detected'; - - const payload = { - channel: '#tmz-alerts', - text: `Hello Theme Daily Test Matrix: ${failureText}`, - blocks: [ - { - type: 'section', - text: { - type: 'mrkdwn', - text: `*❌ Hello Theme Daily Test Matrix Failed*\n\n<${workflowUrl}|View Workflow Run>` - } - }, - { - type: 'divider' - }, - { - type: 'section', - fields: fields - }, - { - type: 'context', - elements: [ - { - type: 'mrkdwn', - text: `Triggered by: ${actor} | Event: ${eventName}` - } - ] - } - ] - }; - - const https = require('https'); - const payloadStr = JSON.stringify(payload); - const data = Buffer.from(payloadStr, 'utf8'); - - const options = { - hostname: 'slack.com', - port: 443, - path: '/api/chat.postMessage', - method: 'POST', - headers: { - 'Authorization': `Bearer ${slackToken}`, - 'Content-Type': 'application/json', - 'Content-Length': data.length - } - }; - - const req = https.request(options, (res) => { - let responseData = ''; - res.on('data', (chunk) => { - responseData += chunk; - }); - res.on('end', () => { - if (res.statusCode === 200) { - const response = JSON.parse(responseData); - if (response.ok) { - console.log('✅ Slack notification sent'); - } else { - console.error('Slack API error:', response.error); - } - } else { - console.error(`Slack API returned status ${res.statusCode}`); - } - process.exit(0); - }); - }); - - req.on('error', (error) => { - console.error('Request error:', error.message); - process.exit(0); - }); - - req.write(data); - req.end(); - NODE_SCRIPT + WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + SLACK_CHANNEL: '#tmz-hello-delivery' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 70ca0a55..1dcba52a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -526,7 +526,7 @@ jobs: if: ${{ inputs.dry_run == false && inputs.deploy_to_wporg == true }} uses: ./.github/actions/theme-slack-notification-release with: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + CLOUD_SLACK_BOT_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN }} PACKAGE_VERSION: ${{ env.PACKAGE_VERSION }} BUILD_ZIP_PATH: ${{ env.BUILD_ZIP_PATH }} GITHUB_RELEASE_URL: ${{ env.RELEASE_URL }} From ed0ad77eeff041bd319b3a64ed08aa58a7114b6d Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin Date: Wed, 26 Nov 2025 10:24:46 +0200 Subject: [PATCH 09/16] Send slack message --- .github/workflows/daily-test-matrix.yml | 35 +++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/.github/workflows/daily-test-matrix.yml b/.github/workflows/daily-test-matrix.yml index 960cb7db..8416681a 100644 --- a/.github/workflows/daily-test-matrix.yml +++ b/.github/workflows/daily-test-matrix.yml @@ -89,6 +89,41 @@ jobs: targeted-tests: ${{ steps.matrix.outputs.targeted-tests }} hello-theme-version-for-display: ${{ steps.matrix.outputs.hello-theme-version-for-display }} steps: + - name: Checkout for scripts + uses: actions/checkout@v4 + + - name: Test Slack notification + continue-on-error: true + env: + CLOUD_SLACK_BOT_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN }} + SLACK_CHANNEL: '#tmz-hello-delivery' + run: | + export CLOUD_SLACK_BOT_TOKEN SLACK_CHANNEL + + node << 'NODE_SCRIPT' + const slackChannel = process.env.SLACK_CHANNEL || '#tmz-hello-delivery'; + + const payload = { + text: 'Test by Hein: Slack notification inside the Daily Test Matrix is working for the Hello Theme', + blocks: [ + { + type: 'section', + text: { + type: 'mrkdwn', + text: 'Test by Hein: Slack notification inside the Daily Test Matrix is working for the Hello Theme' + } + } + ] + }; + + process.env.SLACK_PAYLOAD = JSON.stringify(payload); + + const { execSync } = require('child_process'); + const path = require('path'); + const scriptPath = path.join(process.env.GITHUB_WORKSPACE, '.github/scripts/send-slack-message.js'); + execSync(`node "${scriptPath}"`, { stdio: 'inherit', env: process.env }); + NODE_SCRIPT + - name: Calculate version matrix id: matrix run: | From 0431137fa1cfc11cc87532c413f4b1809e1ea95b Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin Date: Wed, 26 Nov 2025 10:30:51 +0200 Subject: [PATCH 10/16] Clean up --- .../action.yml | 4 +- .../action.yml | 4 +- .github/scripts/send-slack-message.js | 2 +- .github/workflows/daily-test-matrix.yml | 37 +------------------ 4 files changed, 6 insertions(+), 41 deletions(-) diff --git a/.github/actions/theme-slack-notification-daily-tests/action.yml b/.github/actions/theme-slack-notification-daily-tests/action.yml index af94ebf8..f6cad667 100644 --- a/.github/actions/theme-slack-notification-daily-tests/action.yml +++ b/.github/actions/theme-slack-notification-daily-tests/action.yml @@ -9,7 +9,7 @@ inputs: description: 'GitHub workflow run URL' SLACK_CHANNEL: required: false - default: '#tmz-hello-delivery' + default: '#tmz-alerts' description: 'Slack channel to send notification to' runs: @@ -26,7 +26,7 @@ runs: node << 'NODE_SCRIPT' const workflowUrl = process.env.WORKFLOW_URL || ''; - const slackChannel = process.env.SLACK_CHANNEL || '#tmz-hello-delivery'; + const slackChannel = process.env.SLACK_CHANNEL || '#tmz-alerts'; const payload = { text: 'Failing test alert', diff --git a/.github/actions/theme-slack-notification-release/action.yml b/.github/actions/theme-slack-notification-release/action.yml index e1ba137f..29b53f4d 100644 --- a/.github/actions/theme-slack-notification-release/action.yml +++ b/.github/actions/theme-slack-notification-release/action.yml @@ -15,7 +15,7 @@ inputs: description: 'GitHub release URL' SLACK_CHANNEL: required: false - default: '#general' + default: '#tmz-hello-delivery' description: 'Slack channel to send notification to' WPORG_DEPLOYMENT_STATUS: required: false @@ -69,7 +69,7 @@ runs: export CLOUD_SLACK_BOT_TOKEN SLACK_CHANNEL PACKAGE_VERSION FILE_SIZE_MB DEPLOYMENT_MESSAGE GITHUB_RELEASE_URL BUILD_ZIP_PATH node << 'NODE_SCRIPT' - const slackChannel = process.env.SLACK_CHANNEL || '#general'; + const slackChannel = process.env.SLACK_CHANNEL || '#tmz-hello-delivery'; const packageVersion = process.env.PACKAGE_VERSION || ''; const fileSizeMb = process.env.FILE_SIZE_MB || 'Unknown'; const deploymentMessage = (process.env.DEPLOYMENT_MESSAGE || '').replace(/\\n/g, '\n'); diff --git a/.github/scripts/send-slack-message.js b/.github/scripts/send-slack-message.js index fb971858..1623f654 100644 --- a/.github/scripts/send-slack-message.js +++ b/.github/scripts/send-slack-message.js @@ -1,7 +1,7 @@ const https = require('https'); const slackToken = process.env.CLOUD_SLACK_BOT_TOKEN || ''; -const slackChannel = process.env.SLACK_CHANNEL || '#general'; +const slackChannel = process.env.SLACK_CHANNEL || '#tmz-alerts'; const payloadJson = process.env.SLACK_PAYLOAD || '{}'; if (!slackToken) { diff --git a/.github/workflows/daily-test-matrix.yml b/.github/workflows/daily-test-matrix.yml index 8416681a..d693bec9 100644 --- a/.github/workflows/daily-test-matrix.yml +++ b/.github/workflows/daily-test-matrix.yml @@ -89,41 +89,6 @@ jobs: targeted-tests: ${{ steps.matrix.outputs.targeted-tests }} hello-theme-version-for-display: ${{ steps.matrix.outputs.hello-theme-version-for-display }} steps: - - name: Checkout for scripts - uses: actions/checkout@v4 - - - name: Test Slack notification - continue-on-error: true - env: - CLOUD_SLACK_BOT_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN }} - SLACK_CHANNEL: '#tmz-hello-delivery' - run: | - export CLOUD_SLACK_BOT_TOKEN SLACK_CHANNEL - - node << 'NODE_SCRIPT' - const slackChannel = process.env.SLACK_CHANNEL || '#tmz-hello-delivery'; - - const payload = { - text: 'Test by Hein: Slack notification inside the Daily Test Matrix is working for the Hello Theme', - blocks: [ - { - type: 'section', - text: { - type: 'mrkdwn', - text: 'Test by Hein: Slack notification inside the Daily Test Matrix is working for the Hello Theme' - } - } - ] - }; - - process.env.SLACK_PAYLOAD = JSON.stringify(payload); - - const { execSync } = require('child_process'); - const path = require('path'); - const scriptPath = path.join(process.env.GITHUB_WORKSPACE, '.github/scripts/send-slack-message.js'); - execSync(`node "${scriptPath}"`, { stdio: 'inherit', env: process.env }); - NODE_SCRIPT - - name: Calculate version matrix id: matrix run: | @@ -771,4 +736,4 @@ jobs: with: CLOUD_SLACK_BOT_TOKEN: ${{ secrets.CLOUD_SLACK_BOT_TOKEN }} WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - SLACK_CHANNEL: '#tmz-hello-delivery' + SLACK_CHANNEL: '#tmz-alerts' From a89bbfca310fbfb918fc93c1183dc5233ecf3fdb Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin <94352322+hein-obox@users.noreply.github.com> Date: Wed, 26 Nov 2025 10:32:25 +0200 Subject: [PATCH 11/16] Potential fix for code scanning alert no. 48: Log injection Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .github/scripts/send-slack-message.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/scripts/send-slack-message.js b/.github/scripts/send-slack-message.js index 1623f654..27c235b3 100644 --- a/.github/scripts/send-slack-message.js +++ b/.github/scripts/send-slack-message.js @@ -54,7 +54,9 @@ const req = https.request(options, (res) => { }); req.on('error', (error) => { - console.error('Request error:', error.message); + // Remove newline characters from error message before logging + const sanitizedMessage = typeof error.message === "string" ? error.message.replace(/[\r\n]+/g, "") : String(error.message); + console.error('Request error:', sanitizedMessage); process.exit(0); }); From 4eea64882295021564e0db708807271712a549b3 Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin <94352322+hein-obox@users.noreply.github.com> Date: Wed, 26 Nov 2025 10:35:16 +0200 Subject: [PATCH 12/16] Potential fix for code scanning alert no. 49: Log injection Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .github/scripts/send-slack-message.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/send-slack-message.js b/.github/scripts/send-slack-message.js index 27c235b3..038470db 100644 --- a/.github/scripts/send-slack-message.js +++ b/.github/scripts/send-slack-message.js @@ -54,8 +54,8 @@ const req = https.request(options, (res) => { }); req.on('error', (error) => { - // Remove newline characters from error message before logging - const sanitizedMessage = typeof error.message === "string" ? error.message.replace(/[\r\n]+/g, "") : String(error.message); + // Remove control characters from error message before logging + const sanitizedMessage = String(error.message).replace(/[\r\n\t\v\f]+/g, ""); console.error('Request error:', sanitizedMessage); process.exit(0); }); From e77a0f5c85b3820656099e2ff13a6690c8178b79 Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin Date: Wed, 26 Nov 2025 11:55:55 +0200 Subject: [PATCH 13/16] Remove error logging --- .github/scripts/send-slack-message.js | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/.github/scripts/send-slack-message.js b/.github/scripts/send-slack-message.js index 038470db..c383ff11 100644 --- a/.github/scripts/send-slack-message.js +++ b/.github/scripts/send-slack-message.js @@ -39,24 +39,13 @@ const req = https.request(options, (res) => { responseData += chunk; }); res.on('end', () => { - if (res.statusCode === 200) { - const response = JSON.parse(responseData); - if (response.ok) { - console.log('✅ Slack notification sent'); - } else { - console.error('Slack API error:', response.error); - } - } else { - console.error(`Slack API returned status ${res.statusCode}`); - } + const response = JSON.parse(responseData); + if (res.statusCode === 200 && response.ok) console.log('✅ Slack notification sent'); process.exit(0); }); }); -req.on('error', (error) => { - // Remove control characters from error message before logging - const sanitizedMessage = String(error.message).replace(/[\r\n\t\v\f]+/g, ""); - console.error('Request error:', sanitizedMessage); +req.on('error', () => { process.exit(0); }); From 3771346b60039338336ae8ce79002306765bfbb2 Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin <94352322+hein-obox@users.noreply.github.com> Date: Wed, 26 Nov 2025 12:01:30 +0200 Subject: [PATCH 14/16] Update .github/scripts/send-slack-message.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/scripts/send-slack-message.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/scripts/send-slack-message.js b/.github/scripts/send-slack-message.js index c383ff11..292d338a 100644 --- a/.github/scripts/send-slack-message.js +++ b/.github/scripts/send-slack-message.js @@ -45,7 +45,8 @@ const req = https.request(options, (res) => { }); }); -req.on('error', () => { +req.on('error', (error) => { + console.error('Failed to send Slack notification:', error.message || error); process.exit(0); }); From a24161f1d855a81f66c367150f4c0bb2d551b54d Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin Date: Wed, 26 Nov 2025 12:07:50 +0200 Subject: [PATCH 15/16] wip --- .github/scripts/send-slack-message.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/send-slack-message.js b/.github/scripts/send-slack-message.js index 292d338a..dbd9e5cc 100644 --- a/.github/scripts/send-slack-message.js +++ b/.github/scripts/send-slack-message.js @@ -46,7 +46,7 @@ const req = https.request(options, (res) => { }); req.on('error', (error) => { - console.error('Failed to send Slack notification:', error.message || error); + console.error('Failed to send Slack notification'); process.exit(0); }); From 6ad51402ffd5f57397b3ad7d9b4e516104382482 Mon Sep 17 00:00:00 2001 From: Hein van Vlastuin Date: Wed, 26 Nov 2025 12:27:36 +0200 Subject: [PATCH 16/16] Remove redundant exports --- .github/actions/theme-slack-notification-daily-tests/action.yml | 2 -- .github/actions/theme-slack-notification-release/action.yml | 2 -- 2 files changed, 4 deletions(-) diff --git a/.github/actions/theme-slack-notification-daily-tests/action.yml b/.github/actions/theme-slack-notification-daily-tests/action.yml index f6cad667..cec85b0a 100644 --- a/.github/actions/theme-slack-notification-daily-tests/action.yml +++ b/.github/actions/theme-slack-notification-daily-tests/action.yml @@ -22,8 +22,6 @@ runs: WORKFLOW_URL: ${{ inputs.WORKFLOW_URL }} SLACK_CHANNEL: ${{ inputs.SLACK_CHANNEL }} run: | - export CLOUD_SLACK_BOT_TOKEN WORKFLOW_URL SLACK_CHANNEL - node << 'NODE_SCRIPT' const workflowUrl = process.env.WORKFLOW_URL || ''; const slackChannel = process.env.SLACK_CHANNEL || '#tmz-alerts'; diff --git a/.github/actions/theme-slack-notification-release/action.yml b/.github/actions/theme-slack-notification-release/action.yml index 29b53f4d..03c1a60f 100644 --- a/.github/actions/theme-slack-notification-release/action.yml +++ b/.github/actions/theme-slack-notification-release/action.yml @@ -66,8 +66,6 @@ runs: GITHUB_RELEASE_URL: ${{ inputs.GITHUB_RELEASE_URL }} BUILD_ZIP_PATH: ${{ inputs.BUILD_ZIP_PATH }} run: | - export CLOUD_SLACK_BOT_TOKEN SLACK_CHANNEL PACKAGE_VERSION FILE_SIZE_MB DEPLOYMENT_MESSAGE GITHUB_RELEASE_URL BUILD_ZIP_PATH - node << 'NODE_SCRIPT' const slackChannel = process.env.SLACK_CHANNEL || '#tmz-hello-delivery'; const packageVersion = process.env.PACKAGE_VERSION || '';