diff --git a/.github/workflows/upload-readmes.yml b/.github/workflows/upload-readmes.yml new file mode 100644 index 000000000..88f4c4aca --- /dev/null +++ b/.github/workflows/upload-readmes.yml @@ -0,0 +1,42 @@ +name: Upload README.md files +on: + push: + branches: + - 'main' + paths: + - 'packages/*/README.md' + workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true +jobs: + upload-readmes: + name: Upload README.md files + runs-on: ubuntu-latest + env: + TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} + TURBO_TEAM: ${{ vars.TURBO_TEAM }} + if: github.repository_owner == 'discordjs' + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Install Node.js + uses: actions/setup-node@v6 + with: + node-version: 24 + package-manager-cache: false + + - name: Install dependencies + uses: ./packages/actions/src/pnpmCache + + - name: Build dependencies + run: pnpm --filter @discordjs/actions... run build + + - name: Upload README.md files + env: + CF_R2_READMES_ACCESS_KEY_ID: ${{ secrets.CF_R2_READMES_ACCESS_KEY_ID }} + CF_R2_READMES_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_READMES_SECRET_ACCESS_KEY }} + CF_R2_READMES_BUCKET: ${{ secrets.CF_R2_READMES_BUCKET }} + CF_R2_READMES_URL: ${{ secrets.CF_R2_READMES_URL }} + uses: ./packages/actions/src/uploadReadmeFiles diff --git a/packages/actions/src/uploadReadmeFiles/action.yml b/packages/actions/src/uploadReadmeFiles/action.yml new file mode 100644 index 000000000..4436ddbdf --- /dev/null +++ b/packages/actions/src/uploadReadmeFiles/action.yml @@ -0,0 +1,5 @@ +name: 'Upload README.md files' +description: 'Uploads the README.md files for packages that have api-extractor.json to the website.' +runs: + using: node24 + main: ../../dist/uploadReadmeFiles/index.js diff --git a/packages/actions/src/uploadReadmeFiles/index.ts b/packages/actions/src/uploadReadmeFiles/index.ts new file mode 100644 index 000000000..6a0be8bd8 --- /dev/null +++ b/packages/actions/src/uploadReadmeFiles/index.ts @@ -0,0 +1,59 @@ +import { readFile } from 'node:fs/promises'; +import process from 'node:process'; +import { info, setFailed } from '@actions/core'; +import { create } from '@actions/glob'; +import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3'; + +if ( + !process.env.CF_R2_READMES_ACCESS_KEY_ID || + !process.env.CF_R2_READMES_SECRET_ACCESS_KEY || + !process.env.CF_R2_READMES_BUCKET || + !process.env.CF_R2_READMES_URL +) { + setFailed('Missing environment variables.'); + process.exit(1); +} + +const S3READMEFiles = new S3Client({ + region: 'auto', + endpoint: process.env.CF_R2_READMES_URL, + credentials: { + accessKeyId: process.env.CF_R2_READMES_ACCESS_KEY_ID, + secretAccessKey: process.env.CF_R2_READMES_SECRET_ACCESS_KEY, + }, + requestChecksumCalculation: 'WHEN_REQUIRED', + responseChecksumValidation: 'WHEN_REQUIRED', +}); + +const promises = []; + +// Find all packages with an api-extractor.json file. +const globber = await create('packages/*/api-extractor.json'); + +for await (const apiExtractorFile of globber.globGenerator()) { + const readmePath = apiExtractorFile.replace('/api-extractor.json', '/README.md'); + const packageName = apiExtractorFile.split('/').at(-2)!; + const readmeKey = `${packageName}/home-README.md`; + info(`Uploading ${readmePath}...`); + + promises.push( + // eslint-disable-next-line promise/prefer-await-to-then + readFile(readmePath, 'utf8').then(async (readmeData) => + S3READMEFiles.send( + new PutObjectCommand({ + Bucket: process.env.CF_R2_READMES_BUCKET, + Key: readmeKey, + Body: readmeData, + }), + ), + ), + ); +} + +try { + await Promise.all(promises); + info('All README.md files uploaded successfully!'); +} catch (error) { + setFailed(`Failed to upload README files: ${error}`); + process.exit(1); +} diff --git a/packages/actions/tsup.config.ts b/packages/actions/tsup.config.ts index d1438612c..6bd00cc05 100644 --- a/packages/actions/tsup.config.ts +++ b/packages/actions/tsup.config.ts @@ -6,6 +6,7 @@ export default createTsupConfig({ 'src/formatTag/index.ts', 'src/releasePackages/index.ts', 'src/uploadDocumentation/index.ts', + 'src/uploadReadmeFiles/index.ts', 'src/uploadSearchIndices/index.ts', 'src/uploadSplitDocumentation/index.ts', ],