From 92798a6cce212922c66138a1ab6555e8dbfaac6e Mon Sep 17 00:00:00 2001 From: Kunal Mehta Date: Thu, 15 Aug 2024 12:46:33 -0400 Subject: [PATCH] Migrate translation-tests to GitHub Actions Translation tests are slow because it's our normal tests just run 20+ times, once for each language. We can use a dynamic matrix to generate separate jobs pretty easily (I learned this pattern from https://github.com/suzuki-shunsuke/example-github-actions-dynamic-matrix). This job is a little special as we only run it in specific circumstances. Two are easy to handle 1) branch filter and 2) scheduled run. But only triggering on PRs from "weblate-fpf" is a bit harder, so we add some run-time logic in the locales job itself. --- .circleci/config.yml | 58 ------------------------------- .github/workflows/translation.yml | 58 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 58 deletions(-) create mode 100644 .github/workflows/translation.yml diff --git a/.circleci/config.yml b/.circleci/config.yml index 1dd1a02227..4e2abc8f86 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -101,47 +101,6 @@ jobs: DOCKER_BUILD_ARGUMENTS="--cache-from securedrop-test-focal-py3:${fromtag:-latest}" securedrop/bin/dev-shell \ bash -c "/opt/venvs/securedrop-app-code/bin/pip3 install --require-hashes -r requirements/python3/develop-requirements.txt && make -C .. verify-mo" - translation-tests: - machine: - image: ubuntu-2004:current - enabled: true - environment: - DOCKER_API_VERSION: 1.24 - BASE_OS: focal - parallelism: 21 - steps: - - run: - name: Only run on translation pull requests - command: | - if [ "$CIRCLE_PR_USERNAME" != "weblate-fpf" ]; then - circleci-agent step halt - fi - - - checkout - - *rebaseontarget - - *createcachedir - - *restorecache - - *loadimagelayers - - *dockerimagebuild - - *saveimagelayers - - *savecache - - - run: - name: Run tests - command: | - sudo apt update && sudo apt install python3-sh python3-babel - NUM_SUPPORTED_LOCALES="$(make count-supported-locales)" - [[ "$NUM_SUPPORTED_LOCALES" -eq "$CIRCLE_NODE_TOTAL" ]] || { echo "Parallelism (${CIRCLE_NODE_TOTAL} must equal the number of supported languages (${NUM_SUPPORTED_LOCALES})."; exit 1; } - export LOCALES="$(make supported-locales | jq --raw-output 'join("\n")' | circleci tests split)" - fromtag=$(docker images | grep securedrop-test-focal-py3 | head -n1 | awk '{print $2}') - DOCKER_BUILD_ARGUMENTS="--cache-from securedrop-test-focal-py3:${fromtag:-latest}" make translation-test - - - store_test_results: - path: ~/project/test-results - - - store_artifacts: - path: ~/project/test-results - staging-test-with-rebase: machine: image: ubuntu-2004:current @@ -189,12 +148,6 @@ workflows: context: - circleci-slack <<: *slack-fail-post-step - - translation-tests: - requires: - - lint - context: - - circleci-slack - <<: *slack-fail-post-step nightly: triggers: @@ -206,14 +159,3 @@ workflows: - develop jobs: - staging-test-with-rebase - - weekly: - triggers: - - schedule: - cron: "0 0 * * 0" - filters: - branches: - only: - - develop - jobs: - - translation-tests diff --git a/.github/workflows/translation.yml b/.github/workflows/translation.yml new file mode 100644 index 0000000000..e28c61e61e --- /dev/null +++ b/.github/workflows/translation.yml @@ -0,0 +1,58 @@ +name: Translation +on: + push: + branches: + - 'l10n-*' + pull_request: + schedule: + # Weekly on Sundays + - cron: '0 3 * * 0' + +# Only build for latest push/PR unless it's main or release/ +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !startsWith( github.ref, 'refs/heads/release/' ) }} + +jobs: + locales: + runs-on: ubuntu-latest + outputs: + locales: ${{ steps.locales.outputs.locales }} + steps: + - uses: actions/checkout@v4 + - name: Generate locale list + id: locales + run: | + # We only want to run if it's: + # 1. A pull request from the weblate-fpf user + # 2. A scheduled run + # 3. A push to a `l10n-*` branch + # Two and Three are checked above, so we just need to check One. + if [ "${{ github.event_name }}" = "pull_request" ] && [ "${{ github.actor }}" = "weblate-fpf" ]; then + echo "locales=$(make supported-locales)" >> "$GITHUB_OUTPUT" + else + if [ "${{ github.event_name }}" != "pull_request" ]; then + echo "locales=$(make supported-locales)" >> "$GITHUB_OUTPUT" + else + # skip: non weblate-fpf PR, just output an empty list + echo "locales=[]" >> "$GITHUB_OUTPUT" + fi + fi + + test: + runs-on: ubuntu-latest + needs: locales + # If we're in the skip case above, we'll have an empty list + if: "join(fromJSON(needs.locales.outputs.locales), '') != ''" + strategy: + fail-fast: false + matrix: + locale: ${{ fromJson(needs.locales.outputs.locales) }} + steps: + - uses: actions/checkout@v4 + - name: Build image + run: | + DOCKER_BUILD_VERBOSE=true ./securedrop/bin/dev-shell true + - name: Run translation tests + run: | + LOCALES="${{ matrix.locale }}" make translation-test