diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 4f8d311c2d..238f06cdc0 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -689,7 +689,12 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.ALGOLIA_BOT_TOKEN }} - - name: Push generation to the Algolia docs + - name: Push specs and snippets to algolia/doc run: yarn workspace scripts pushToAlgoliaDoc env: GITHUB_TOKEN: ${{ secrets.ALGOLIA_BOT_TOKEN }} + + - name: Push guides to algolia/AlgoliaWeb + run: yarn workspace scripts pushToAlgoliaWeb + env: + GITHUB_TOKEN: ${{ secrets.ALGOLIA_BOT_TOKEN }} diff --git a/.github/workflows/push-to-algolia-web.yml b/.github/workflows/push-to-algolia-web.yml new file mode 100644 index 0000000000..60d9f4eda8 --- /dev/null +++ b/.github/workflows/push-to-algolia-web.yml @@ -0,0 +1,24 @@ +name: Push snippets to AlgoliaWeb + +on: workflow_dispatch + +jobs: + push: + name: Manual trigger push for onboarding guides + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: main + + - name: Setup + id: setup + uses: ./.github/actions/setup + with: + type: minimal + + - run: yarn workspace scripts pushToAlgoliaWeb + env: + GITHUB_TOKEN: ${{ secrets.ALGOLIA_BOT_TOKEN }} + FORCE: true diff --git a/scripts/ci/codegen/pushToAlgoliaWeb.ts b/scripts/ci/codegen/pushToAlgoliaWeb.ts new file mode 100644 index 0000000000..ae7e6097ed --- /dev/null +++ b/scripts/ci/codegen/pushToAlgoliaWeb.ts @@ -0,0 +1,126 @@ +import fsp from 'fs/promises'; +import { resolve } from 'path'; + +import { + configureGitHubAuthor, + ensureGitHubToken, + exists, + getOctokit, + gitBranchExists, + gitCommit, + LANGUAGES, + OWNER, + run, + setVerbose, + toAbsolutePath, +} from '../../common.js'; +import { getNbGitDiff } from '../utils.js'; + +import { getClientsConfigField } from '../../config.js'; +import { commitStartRelease } from './text.js'; + +async function generateJSON(outputFile: string): Promise { + const guides = {}; + for (const language of LANGUAGES) { + if (!(await exists(toAbsolutePath(`docs/guides/${language}`)))) { + continue; + } + + const pathToGuides = toAbsolutePath( + `docs/guides/${language}/${getClientsConfigField(language, ['snippets', 'outputFolder'])}`, + ); + const files = await fsp.readdir(pathToGuides); + for (const file of files) { + const extension = getClientsConfigField(language, ['snippets', 'extension']); + if (!file.endsWith(extension)) { + continue; + } + + const guideName = file.replaceAll(extension, ''); + if (!guides[guideName]) { + guides[guideName] = {}; + } + + guides[guideName][language] = (await fsp.readFile(`${pathToGuides}/${file}`, 'utf-8')) + .replace('ALGOLIA_APPLICATION_ID', 'YourApplicationID') + .replace('ALGOLIA_API_KEY', 'YourWriteAPIKey') + .replace('', 'movies_index'); + } + } + + await fsp.writeFile(outputFile, JSON.stringify(guides, null, 2)); +} + +async function pushToAlgoliaWeb(): Promise { + const githubToken = ensureGitHubToken(); + + const repository = 'AlgoliaWeb'; + const lastCommitMessage = await run('git log -1 --format="%s"'); + const author = (await run('git log -1 --format="Co-authored-by: %an <%ae>"')).trim(); + const coAuthors = (await run('git log -1 --format="%(trailers:key=Co-authored-by)"')) + .split('\n') + .map((coAuthor) => coAuthor.trim()) + .filter(Boolean); + + if (!process.env.FORCE && !lastCommitMessage.startsWith(commitStartRelease)) { + return; + } + + const targetBranch = 'feat/automated-update-from-api-clients-automation-repository'; + const githubURL = `https://${githubToken}:${githubToken}@github.com/${OWNER}/${repository}`; + const tempGitDir = resolve(process.env.RUNNER_TEMP! || toAbsolutePath('foo/local/test'), repository); + await fsp.rm(tempGitDir, { force: true, recursive: true }); + await run(`git clone --depth 1 ${githubURL} ${tempGitDir}`); + + const outputFile = toAbsolutePath(`${tempGitDir}/_client/src/routes/launchpad/onboarding-snippets.json`); + + console.log(`Generating JSON output file from guides at path ${outputFile}`); + + await generateJSON(outputFile); + + console.log(`Pushing to ${OWNER}/${repository}`); + if (await gitBranchExists(targetBranch, tempGitDir)) { + await run(`git fetch origin ${targetBranch}`, { cwd: tempGitDir }); + await run(`git push -d origin ${targetBranch}`, { cwd: tempGitDir }); + } + await run(`git checkout -B ${targetBranch}`, { cwd: tempGitDir }); + + if ((await getNbGitDiff({ head: null, cwd: tempGitDir })) === 0) { + console.log('❎ Skipping push to AlgoliaWeb because there is no change.'); + + return; + } + + await configureGitHubAuthor(tempGitDir); + + const message = 'feat: update generated guides'; + await run('git add .', { cwd: tempGitDir }); + await gitCommit({ + message, + coAuthors: [author, ...coAuthors], + cwd: tempGitDir, + }); + await run(`git push -f -u origin ${targetBranch}`, { cwd: tempGitDir }); + + console.log(`Creating pull request on ${OWNER}/${repository}...`); + const octokit = getOctokit(); + const { data } = await octokit.pulls.create({ + owner: OWNER, + repo: repository, + title: message, + body: [ + 'This PR is automatically created by https://github.com/algolia/api-clients-automation', + 'It contains the latest generated guides.', + ].join('\n\n'), + base: 'develop', + head: targetBranch, + }); + + console.log(`Pull request created on ${OWNER}/${repository}`); + console.log(` > ${data.url}`); +} + +if (import.meta.url.endsWith(process.argv[1])) { + setVerbose(false); + pushToAlgoliaWeb(); +} diff --git a/scripts/package.json b/scripts/package.json index 4f3ab08b14..0035958126 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -13,6 +13,7 @@ "pre-commit": "node ./ci/husky/pre-commit.mjs", "pushGeneratedCode": "yarn runScript dist/ci/codegen/pushGeneratedCode.js", "pushToAlgoliaDoc": "yarn runScript dist/ci/codegen/pushToAlgoliaDoc.js", + "pushToAlgoliaWeb": "yarn runScript dist/ci/codegen/pushToAlgoliaWeb.js", "runScript": "NODE_NO_WARNINGS=1 node --enable-source-maps", "setRunVariables": "yarn runScript dist/ci/githubActions/setRunVariables.js", "spreadGeneration": "yarn runScript dist/ci/codegen/spreadGeneration.js", diff --git a/yarn.lock b/yarn.lock index a5fccda99c..f6118c0caa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -257,6 +257,12 @@ __metadata: languageName: node linkType: soft +"@algolia/monitoring@link:../../../clients/algoliasearch-client-javascript/packages/monitoring::locator=javascript-playground%40workspace%3Aplayground%2Fjavascript%2Fnode": + version: 0.0.0-use.local + resolution: "@algolia/monitoring@link:../../../clients/algoliasearch-client-javascript/packages/monitoring::locator=javascript-playground%40workspace%3Aplayground%2Fjavascript%2Fnode" + languageName: node + linkType: soft + "@algolia/monitoring@link:../../../clients/algoliasearch-client-javascript/packages/monitoring::locator=javascript-snippets%40workspace%3Adocs%2Fsnippets%2Fjavascript": version: 0.0.0-use.local resolution: "@algolia/monitoring@link:../../../clients/algoliasearch-client-javascript/packages/monitoring::locator=javascript-snippets%40workspace%3Adocs%2Fsnippets%2Fjavascript" @@ -5231,6 +5237,7 @@ __metadata: "@algolia/client-query-suggestions": "link:../../../clients/algoliasearch-client-javascript/packages/client-query-suggestions" "@algolia/client-search": "link:../../../clients/algoliasearch-client-javascript/packages/client-search" "@algolia/ingestion": "link:../../../clients/algoliasearch-client-javascript/packages/ingestion" + "@algolia/monitoring": "link:../../../clients/algoliasearch-client-javascript/packages/monitoring" "@algolia/recommend": "link:../../../clients/algoliasearch-client-javascript/packages/recommend" "@algolia/requester-node-http": "link:../../../clients/algoliasearch-client-javascript/packages/requester-node-http" algoliasearch: "link:../../../clients/algoliasearch-client-javascript/packages/algoliasearch"