diff --git a/.github/workflows/scheduled.yml b/.github/workflows/scheduled.yml index 8f059313879..9df53f3b6f2 100644 --- a/.github/workflows/scheduled.yml +++ b/.github/workflows/scheduled.yml @@ -2,7 +2,7 @@ name: ⏰ Scheduled daily jobs on: schedule: # Every work day of the week at 08:08 - - cron: "8 8 * * MON-FRI" + - cron: '8 8 * * MON-FRI' # Allows you to run this workflow manually from the Actions tab. workflow_dispatch: @@ -19,6 +19,10 @@ jobs: with: deno-version: v1.26.2 + - uses: guardian/actions-setup-node@main + with: + cache: 'yarn' + - name: Run Deno scripts run: scripts/ci-deno.sh env: diff --git a/scripts/ci-deno.sh b/scripts/ci-deno.sh index 344efb12d6c..ada9cb3653b 100755 --- a/scripts/ci-deno.sh +++ b/scripts/ci-deno.sh @@ -17,3 +17,10 @@ deno run \ --allow-net \ --allow-env="GITHUB_TOKEN,CAPI_KEY" \ scripts/deno/iframe-titles.ts + +deno run \ + --no-check=remote \ + --allow-net \ + --allow-env="GITHUB_TOKEN" \ + --allow-run=yarn,npm \ + scripts/deno/peer-dependencies.ts diff --git a/scripts/deno/peer-dependencies.ts b/scripts/deno/peer-dependencies.ts new file mode 100644 index 00000000000..aba90d74a06 --- /dev/null +++ b/scripts/deno/peer-dependencies.ts @@ -0,0 +1,113 @@ +import { octokit } from './github.ts'; + +const peers = async (cwd: string) => { + const process = Deno.run({ + cwd, + cmd: ['yarn', '--force'], + stdout: 'null', + stderr: 'piped', + }); + + const [{ code }, rawOutput] = await Promise.all([ + process.status(), + process.stderrOutput(), + ]); + + if (code !== 0) Deno.exit(code); + + const deps = new TextDecoder() + .decode(rawOutput) + .split('\n') + // keep only incorrect peer dependencies warnings + .filter((line) => line.includes('has incorrect peer dependency')) + // strip out the workspace-aggregator-xyz-012 prefixes + .map((line) => line.replace(/workspace-aggregator-[a-z0-9-]+ > /, '')) + // apps-rendering are not part of the workspace + .map((line) => line.replace('" >', '"@guardian/apps-rendering >')); + + return deps; +}; + +type Workspaces = { dcr: string[]; cr: string[]; ar: string[] }; +const initialValue: Workspaces = { dcr: [], cr: [], ar: [] }; + +const { dcr, ar, cr } = ( + await Promise.all(['.', './apps-rendering'].map(peers)) +) + .flat() + .map((line) => { + const matches = line.match( + /warning "(.*?) > (.+?)" has incorrect peer dependency "(.+)"./, + ); + if (!matches) throw new Error('Invalid string'); + + const [, workspace, dependency, peer] = matches; + + return { workspace, dependency, peer }; + }) + .reduce((acc, { workspace, dependency, peer }) => { + const line = `- [ ] \`${dependency}\` requires peer \`${peer}\``; + switch (workspace) { + case '@guardian/dotcom-rendering': + return { + ...acc, + dcr: acc.dcr.concat(line), + }; + + case '@guardian/common-rendering': + return { + ...acc, + cr: acc.cr.concat(line), + }; + + case '@guardian/apps-rendering': + return { + ...acc, + ar: acc.ar.concat(line), + }; + default: + return acc; + } + }, initialValue); + +const body = `## Current peer dependencies mismatch + +### dotcom-rendering +${dcr.length ? dcr.join('\n') : '- [X] all peer deps matched!'} + +### apps-rendering +${ar.length ? ar.join('\n') : '- [X] all peer deps matched!'} + +### common-rendering +${cr.length ? cr.join('\n') : '- [X] all peer deps matched!'} +`; + +if (!octokit) { + console.log(body); + Deno.exit(); +} + +/** https://github.com/guardian/dotcom-rendering/issues/6945 */ +const issue_number = 6945; + +try { + const { + data: { html_url }, + } = await octokit.rest.issues.update({ + owner: 'guardian', + repo: 'dotcom-rendering', + issue_number, + body, + }); + + console.info(`Updated list of issues for dotcom-rendering#${issue_number}`); + console.info(html_url); +} catch (error) { + // do_something + console.warn(`Failed to update issue #${issue_number}`); + console.error(error); + + console.log(body); +} + +Deno.exit();