From 5c44ad2763bf5f4405986d127faf3901a7ca7132 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Wed, 23 Apr 2025 14:30:35 +0100 Subject: [PATCH] Chore: Initial scaffolding for crowdin action (#104393) * start to scaffold github action * test script * simplify * right path (maybe) * clean up * CONSTANT_CASE * add CODEOWNERS * kick CI --- .github/CODEOWNERS | 2 + .../workflows/i18n-crowdin-create-tasks.yml | 25 ++++++ .../workflows/scripts/crowdin/create-tasks.js | 84 +++++++++++++++++++ package.json | 1 + yarn.lock | 12 ++- 5 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/i18n-crowdin-create-tasks.yml create mode 100644 .github/workflows/scripts/crowdin/create-tasks.js diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 59e6164cb87..67ceca61366 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -814,6 +814,8 @@ embed.go @grafana/grafana-as-code /.github/workflows/core-plugins-build-and-release.yml @grafana/plugins-platform-frontend @grafana/plugins-platform-backend /.github/workflows/i18n-crowdin-upload.yml @grafana/grafana-frontend-platform /.github/workflows/i18n-crowdin-download.yml @grafana/grafana-frontend-platform +/.github/workflows/i18n-crowdin-create-tasks.yml @grafana/grafana-frontend-platform +/.github/workflows/scripts/crowdin/create-tasks.js @grafana/grafana-frontend-platform /.github/workflows/pr-go-workspace-check.yml @grafana/grafana-app-platform-squad /.github/workflows/pr-dependabot-update-go-workspace.yml @grafana/grafana-app-platform-squad /.github/workflows/pr-k8s-codegen-check.yml @grafana/grafana-app-platform-squad diff --git a/.github/workflows/i18n-crowdin-create-tasks.yml b/.github/workflows/i18n-crowdin-create-tasks.yml new file mode 100644 index 00000000000..f12ca3ff7a2 --- /dev/null +++ b/.github/workflows/i18n-crowdin-create-tasks.yml @@ -0,0 +1,25 @@ +name: Crowdin Create Tasks + +on: + workflow_dispatch: + # schedule: + # - cron: "0 0 * * *" + +jobs: + create-tasks-in-crowdin: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + + - name: Create tasks + env: + CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} + run: node ./.github/workflows/scripts/crowdin/create-tasks.js diff --git a/.github/workflows/scripts/crowdin/create-tasks.js b/.github/workflows/scripts/crowdin/create-tasks.js new file mode 100644 index 00000000000..d3085f8afa0 --- /dev/null +++ b/.github/workflows/scripts/crowdin/create-tasks.js @@ -0,0 +1,84 @@ +const crowdin = require('@crowdin/crowdin-api-client'); +const TRANSLATED_CONNECTOR_DESCRIPTION = '{{tos_service_type: premium}}'; + +const API_TOKEN = process.env.CROWDIN_PERSONAL_TOKEN; +if (!API_TOKEN) { + console.error('Error: CROWDIN_PERSONAL_TOKEN environment variable is not set'); + process.exit(1); +} + +const PROJECT_ID = process.env.CROWDIN_PROJECT_ID; +if (!PROJECT_ID) { + console.error('Error: CROWDIN_PROJECT_ID environment variable is not set'); + process.exit(1); +} + +const { tasksApi, projectsGroupsApi, sourceFilesApi } = new crowdin.default({ + token: API_TOKEN, + organization: 'grafana' +}); + +const languages = await getLanguages(); +const fileIds = await getFileIds(); +console.log('Languages: ', languages); +console.log('File IDs: ', fileIds); + +// for (const language of languages) { +// const { name, id } = language; +// await createTask(`Translate to ${name}`, id, fileIds); +// } + +async function getLanguages() { + try { + const project = await projectsGroupsApi.getProject(PROJECT_ID); + const languages = project.data.targetLanguages; + return languages; + } catch (error) { + console.error('Failed to fetch languages: ', error.message); + if (error.response && error.response.data) { + console.error('Error details: ', JSON.stringify(error.response.data, null, 2)); + } + process.exit(1); + } +} + +async function getFileIds() { + try { + const response = await sourceFilesApi.listProjectFiles(PROJECT_ID); + const files = response.data; + const fileIds = files.map(file => file.data.id); + return fileIds; + } catch (error) { + console.error('Failed to fetch file IDs: ', error.message); + if (error.response && error.response.data) { + console.error('Error details: ', JSON.stringify(error.response.data, null, 2)); + } + process.exit(1); + } +} + +async function createTask(title, languageId, fileIds) { + try { + const taskParams = { + title, + description: TRANSLATED_CONNECTOR_DESCRIPTION, + languageId, + type: 2, // Translation by vendor + workflowStepId: 78, // Translation step ID + skipAssignedStrings: true, + fileIds, + }; + + console.log(`Creating Crowdin task: "${title}" for language ${languageId}`); + + const response = await tasksApi.addTask(PROJECT_ID, taskParams); + console.log(`Task created successfully! Task ID: ${response.data.id}`); + return response.data; + } catch (error) { + console.error('Failed to create Crowdin task: ', error.message); + if (error.response && error.response.data) { + console.error('Error details: ', JSON.stringify(error.response.data, null, 2)); + } + process.exit(1); + } +} diff --git a/package.json b/package.json index 9f91adb3250..5e9a44e8f99 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "@babel/runtime": "7.27.0", "@betterer/betterer": "5.4.0", "@betterer/cli": "5.4.0", + "@crowdin/crowdin-api-client": "^1.42.0", "@cypress/webpack-preprocessor": "6.0.4", "@emotion/eslint-plugin": "11.12.0", "@grafana/eslint-config": "8.0.0", diff --git a/yarn.lock b/yarn.lock index 263a8945131..70d29a1635c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1629,6 +1629,15 @@ __metadata: languageName: node linkType: hard +"@crowdin/crowdin-api-client@npm:^1.42.0": + version: 1.42.0 + resolution: "@crowdin/crowdin-api-client@npm:1.42.0" + dependencies: + axios: "npm:^1" + checksum: 10/9e816c5d1fe6f93c0f20625f377f0caa1c2d0cc2a5df97440fc3494ab1d3a7a29d6fe40af8fae32ea96f2bc7fa2bcdc1c7af6dc6563d8fdf86624dc7885e98ff + languageName: node + linkType: hard + "@cspotcode/source-map-support@npm:^0.8.0": version: 0.8.1 resolution: "@cspotcode/source-map-support@npm:0.8.1" @@ -11644,7 +11653,7 @@ __metadata: languageName: node linkType: hard -"axios@npm:^1.7.9, axios@npm:^1.8.2, axios@npm:^1.8.3": +"axios@npm:^1, axios@npm:^1.7.9, axios@npm:^1.8.2, axios@npm:^1.8.3": version: 1.8.4 resolution: "axios@npm:1.8.4" dependencies: @@ -17592,6 +17601,7 @@ __metadata: "@betterer/betterer": "npm:5.4.0" "@betterer/cli": "npm:5.4.0" "@bsull/augurs": "npm:^0.9.0" + "@crowdin/crowdin-api-client": "npm:^1.42.0" "@cypress/webpack-preprocessor": "npm:6.0.4" "@emotion/css": "npm:11.13.5" "@emotion/eslint-plugin": "npm:11.12.0"