diff --git a/.github/actions/telemetry_check/check.mjs b/.github/actions/telemetry_check/check.mjs new file mode 100644 index 000000000000..52837b76f7f5 --- /dev/null +++ b/.github/actions/telemetry_check/check.mjs @@ -0,0 +1,105 @@ +/* eslint-env node */ + +import http from 'http' + +import { exec } from '@actions/exec' + +console.log( + `Telemetry is being redirected to ${process.env.REDWOOD_REDIRECT_TELEMETRY}` +) + +// All the fields we expect inside a telemetry packet +const expectedPacketFields = [ + 'type', + 'command', + 'duration', + 'uid', + 'ci', + 'redwoodCi', + 'NODE_ENV', + 'os', + 'osVersion', + // "shell", // Not expected on windows + 'nodeVersion', + 'yarnVersion', + 'npmVersion', + 'redwoodVersion', + 'system', + 'complexity', + 'sides', + 'webBundler', +] + +// Setup fake telemetry server +const server = http.createServer((req, res) => { + let data = '' + req.on('data', (chunk) => { + data += chunk + }) + req.on('end', () => { + res.writeHead(200) + res.end() + + const packet = JSON.parse(data) + + let hasAllFields = true + for (const field of expectedPacketFields) { + if (packet[field] === undefined) { + hasAllFields = false + console.error(`Telemetry packet is missing field "${field}"`) + } + } + + const isCI = packet.ci ?? false + + if (hasAllFields && isCI) { + console.log('Valid telemetry received') + process.exit(0) + } else { + console.error('Invalid telemetry received') + console.error(packet) + process.exit(1) + } + }) +}) + +// Run the fake telemetry server at the redirected location +const host = process.env.REDWOOD_REDIRECT_TELEMETRY.split(':')[1].slice(2) +const port = parseInt(process.env.REDWOOD_REDIRECT_TELEMETRY.split(':')[2]) +server.listen(port, host, () => { + console.log(`Telemetry listener is running on http://${host}:${port}`) +}) + +// Run a command and await output +try { + const mode = process.argv[process.argv.indexOf('--mode') + 1] + let exitCode = 0 + switch (mode) { + case 'crwa': + exitCode = await exec( + `yarn node ./packages/create-redwood-app/dist/create-redwood-app.js ../project-for-telemetry --typescript false --git false --yarn-install true` + ) + if (exitCode) { + process.exit(1) + } + break + case 'cli': + exitCode = await exec( + `yarn --cwd ../project-for-telemetry node ../redwood/packages/cli/dist/index.js info` + ) + if (exitCode) { + process.exit(1) + } + break + default: + console.error(`Unknown mode: ${mode}`) + process.exit(1) + } +} catch (error) { + console.error(error) +} + +// If we didn't hear the telemetry after 2 mins then let's fail +await new Promise((r) => setTimeout(r, 120_000)) +console.error('No telemetry response within 120 seconds. Failing...') +process.exit(1) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 867ee6a19388..313876592f16 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -324,3 +324,44 @@ jobs: runs-on: ${{ matrix.os }} steps: - run: echo "Only doc changes" + + telemetry-check: + needs: check + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + node-version: [16, 18] + fail-fast: true + name: ๐Ÿ”ญ Telemetry check / ${{ matrix.os }} / node ${{ matrix.node-version }} latest + runs-on: ${{ matrix.os }} + env: + REDWOOD_REDIRECT_TELEMETRY: "http://127.0.0.1:48619" # Random port + steps: + - uses: actions/checkout@v3 + - name: ๐Ÿงถ Set up job + uses: ./.github/actions/set-up-job + with: + node-version: ${{ matrix.node-version }} + + - name: ๐Ÿ”จ Build + run: yarn build + + - name: ๐Ÿ“ข Listen for telemetry (CRWA) + run: node ./.github/actions/telemetry_check/check.mjs --mode crwa + env: + YARN_ENABLE_IMMUTABLE_INSTALLS: false + + - name: ๐Ÿ“ข Listen for telemetry (CLI) + run: node ./.github/actions/telemetry_check/check.mjs --mode cli + + telemetry-check-docs: + needs: only-doc-changes + if: needs.only-doc-changes.outputs.only-doc-changes == 'true' + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + node-version: [16, 18] + name: ๐Ÿ”ญ Telemetry check / ${{ matrix.os }} / node ${{ matrix.node-version }} latest + runs-on: ${{ matrix.os }} + steps: + - run: echo "Only doc changes" diff --git a/packages/telemetry/src/sendTelemetry.ts b/packages/telemetry/src/sendTelemetry.ts index 97f1a3d42f41..a2945cba9d20 100644 --- a/packages/telemetry/src/sendTelemetry.ts +++ b/packages/telemetry/src/sendTelemetry.ts @@ -246,7 +246,9 @@ const uniqueId = (rootDir: string | null) => { // actually call the API with telemetry data export const sendTelemetry = async () => { - const telemetryUrl = 'https://telemetry.redwoodjs.com/api/v1/telemetry' + const telemetryUrl = + process.env.REDWOOD_REDIRECT_TELEMETRY || + 'https://telemetry.redwoodjs.com/api/v1/telemetry' try { const payload = await buildPayload()