From 835db9e19ecb2cef84aa66e04e28ab5ab2e84648 Mon Sep 17 00:00:00 2001 From: Pavel Tkachenko Date: Thu, 30 Jul 2026 12:09:52 +0300 Subject: [PATCH] README: stop teaching the patterns we removed everywhere else MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CI/CD section still described the world before ptc-action, and every defect it taught is one we fixed elsewhere and then shipped a doc contradicting. - The GitHub Actions example was a hand-rolled job with peter-evans/create-pull-request@v5 — an unpinned movable tag on a third-party action, i.e. a write-access foothold. It now leads with ptc-action; the manual steps survive in a
block with the SHA pin, the sha256 check and the stable ptc/translations branch, so a reader who genuinely needs them gets the safe version. - Pins said v1.0.0 while v1.0.3 is current, and the "verify against the checksum published on the release page" instruction had no checksum to point at. The sha256 is now inline next to the curl. - The example config was .ptc/config.yml; `ptc init` writes .ptc-config.yml at the repository root, which is also the path the action auto-detects. - The GitLab job did `chmod +x ptc-cli.sh` on a file it never downloaded, had no image (so no bash on a default Alpine runner), never pushed anything, and gated on the deprecated `only:`. Replaced with the job `ptc init` prints, including the PTC_GIT_PUSH_TOKEN fallback and the [skip ci] guard, plus the note that a Catalog component can never resolve cross-instance. No behaviour change; 180 tests still green (12 + 72 + 22 + 22 + 52). --- README.md | 168 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 111 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 537a908..e1a3a12 100644 --- a/README.md +++ b/README.md @@ -301,22 +301,33 @@ The exit code is the CI-facing verdict, so it reports what actually happened rat ## CI/CD Usage +> **On GitHub Actions, do not do any of this by hand.** Use +> [`OnTheGoSystems/ptc-action`](https://github.com/OnTheGoSystems/ptc-action) — +> it vendors this script at a fixed version, SHA-pins its own dependencies, and +> opens the translation PR for you. The recipe is in +> [GitHub Actions](#github-actions) below. Everything in this section is for +> pipelines that run the CLI directly. + ### Pinning the CLI version Pipelines download the script from a **pinned release tag**, not a moving branch, so a push to `main` can never change what your build runs: ```bash -curl -fsSL https://raw.githubusercontent.com/OnTheGoSystems/ptc-cli/v1.0.0/ptc-cli.sh -o ptc-cli.sh +curl -fsSL https://raw.githubusercontent.com/OnTheGoSystems/ptc-cli/v1.0.3/ptc-cli.sh -o ptc-cli.sh ``` -Use `v1.0.0` to pin an exact release, or the floating `v1` tag to pick up +Use `v1.0.3` to pin an exact release, or the floating `v1` tag to pick up backward-compatible updates automatically. The `ptc init` command scaffolds the pinned URL for you. **Verify the download** against the SHA256 checksum published on the [release page](https://github.com/OnTheGoSystems/ptc-cli/releases): +``` +87efed00bd9345b9a4d5fb1972d8d53525246f6a2a4e6a48ae7d20d67e41362a ptc-cli.sh # v1.0.3 +``` + ```bash # macOS shasum -a 256 ptc-cli.sh @@ -329,64 +340,42 @@ the server can attribute traffic to a specific release. ### GitHub Actions -Add PTC_API_TOKEN to the repository secrets (Settings -> Secrets and variables -> Actions -> New repository secret). -Ensure to turn on the "Allow GitHub Actions to create and approve pull requests" permission in the repository settings (Settings -> Actions -> General -> Workflow permissions). +Add `PTC_API_TOKEN` to the repository secrets (Settings → Secrets and variables → +Actions → New repository secret), and turn on "Allow GitHub Actions to create and +approve pull requests" (Settings → Actions → General → Workflow permissions). + +Then use the action — it vendors this CLI at a fixed version, so nothing is +fetched at job time: ```yaml -name: Process Translation Files +name: Translate on: - workflow_dispatch: # Manual trigger + push: + branches: [main] + paths: ['locales/en.json'] # trigger on SOURCE changes only → loop-safe + workflow_dispatch: {} + +permissions: + contents: write + pull-requests: write jobs: - process-translations: + translate: runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PTC CLI - run: | - curl -fsSL https://raw.githubusercontent.com/OnTheGoSystems/ptc-cli/v1.0.0/ptc-cli.sh -o ptc-cli.sh - chmod +x ptc-cli.sh - - - name: Process translations with PTC CLI - env: - PTC_API_TOKEN: ${{ secrets.PTC_API_TOKEN }} - run: | - ./ptc-cli.sh \ - --config-file .ptc/config.yml \ - --verbose - - - name: Clean up temporary files - run: | - rm -f ptc-cli.sh - - - name: Create Pull Request with translations - if: success() - uses: peter-evans/create-pull-request@v5 + - uses: actions/checkout@v7 + - uses: OnTheGoSystems/ptc-action@v1 with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: "🌐 Update translations via PTC CLI" - title: "🌐 Update translations from PTC" - body: | - ## 🌐 Translation Update - - This PR contains new translations processed by PTC CLI. - - **Triggered by:** ${{ github.event_name }} - **Branch:** ${{ github.ref_name }} - **Commit:** ${{ github.sha }} - - --- - *Auto-generated by GitHub Actions* - delete-branch: true + api-token: ${{ secrets.PTC_API_TOKEN }} + create-pr: true ``` -Sample `.ptc/config.yml` file: +`api-token` is the only input you have to pass: a `.ptc-config.yml` committed at +the repository root is picked up on its own, and with no config at all the action +runs `ptc init` and uses what it detects. Full input list in the +[action README](https://github.com/OnTheGoSystems/ptc-action#inputs-github-action). + +Sample `.ptc-config.yml` (this is what `ptc init` writes): ```yaml source_locale: en @@ -397,21 +386,86 @@ files: output: src/locales/{{lang}}.json ``` +
+Running the CLI directly instead of the action + +The action exists because a hand-rolled job has to get four things right that it +gets wrong by default: pinning the CLI (not `main`), keeping the token out of +`argv`, SHA-pinning the PR action rather than a movable tag, and not +re-triggering itself. If you still want the steps: + +```yaml + - uses: actions/checkout@v7 + + - name: Setup PTC CLI + run: | + curl -fsSL https://raw.githubusercontent.com/OnTheGoSystems/ptc-cli/v1.0.3/ptc-cli.sh -o ptc-cli.sh + echo "87efed00bd9345b9a4d5fb1972d8d53525246f6a2a4e6a48ae7d20d67e41362a ptc-cli.sh" | sha256sum -c - + chmod +x ptc-cli.sh + + - name: Process translations + env: + PTC_API_TOKEN: ${{ secrets.PTC_API_TOKEN }} # env, never --api-token + run: ./ptc-cli.sh --config-file .ptc-config.yml --verbose + + - name: Create Pull Request with translations + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + branch: ptc/translations # stable branch → re-runs update ONE PR + commit-message: "chore(i18n): update translations via PTC" + title: "Update translations from PTC" + delete-branch: true +``` + +
+ ### GitLab CI +`ptc init` prints this job for you, pinned to the CLI version you ran it with. +Store `PTC_API_TOKEN` as a **masked** CI/CD variable (Settings → CI/CD → +Variables) — it is read from the environment, never placed on the command line. + ```yaml -process_translations: +ptc-translate: stage: deploy + image: alpine:3.22 + rules: + - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' + before_script: + - apk add --no-cache bash curl git jq script: + - curl -fsSL https://raw.githubusercontent.com/OnTheGoSystems/ptc-cli/v1.0.3/ptc-cli.sh -o ptc-cli.sh - chmod +x ptc-cli.sh - - ./ptc-cli.sh -c config.yml -v - variables: - PTC_API_TOKEN: "$CI_PTC_API_TOKEN" - only: - - merge_requests - - main + - ./ptc-cli.sh --config-file .ptc-config.yml + - | + if ! git diff --quiet; then + git config user.email "ci@ptc" + git config user.name "PTC Translate" + git checkout -B ptc/translations + git add -A + git commit -m "chore(i18n): update translations via PTC [skip ci]" + git push -o merge_request.create \ + -o merge_request.target="$CI_DEFAULT_BRANCH" \ + -o merge_request.title="Update translations from PTC" \ + -f "https://gitlab-ci-token:${PTC_GIT_PUSH_TOKEN:-$CI_JOB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" HEAD:ptc/translations + fi ``` +**The push needs a token that may write to the repository.** `CI_JOB_TOKEN` can, +but only if a maintainer enables Settings → CI/CD → Job token permissions → +*"Allow Git push requests to the repository"* (GitLab 18.4+, off by default). +Otherwise set `PTC_GIT_PUSH_TOKEN` to a project access token with the +`write_repository` scope, also masked. + +Loop-safe twice over: the job only runs on a push to the default branch — the +translation push targets `ptc/translations`, so it cannot re-trigger — and the +commit carries `[skip ci]`, the only skip token GitLab honours. + +There is no GitLab CI/CD Catalog component. `include: component:` is resolved +against the reader's **own** instance, so a component we publish on one server +can never be included from gitlab.com or from a self-hosted install. + ### Additional Translation Files When using YAML configuration, you can specify additional files to be generated (useful for WordPress):