Skip to content

feat!: convert to a node24 JavaScript action - #322

Merged
andrii-bodnar merged 1 commit into
crowdin:js-actionfrom
minijus:feat/node24-action
Nov 3, 2026
Merged

andrii-bodnar merged 1 commit into
crowdin:js-actionfrom
minijus:feat/node24-action

Conversation

@minijus

@minijus minijus commented Oct 24, 2026

Copy link
Copy Markdown

Closes #321. Also addresses #160 (non-Linux/arm64 runners) and #284 (root-owned files).

This replaces the Docker container action (Dockerfile + entrypoint.sh) with a TypeScript action that runs on node24. The bundled output is in dist/index.js. All existing inputs and outputs are kept, so it can be released as a drop-in v4.

Changes

  • Installing the CLI: the action downloads the native Crowdin CLI binary for the runner from the @crowdin/cli-<platform> npm package. It checks the download against the registry's sha512 integrity hash and caches it with @actions/tool-cache. glibc and musl Linux builds are cached separately. Three new optional inputs:
    • cli_version: defaults to 5.5.0, the same version the old Dockerfile used. Exact versions and dist-tags such as latest are accepted.
    • use_installed_cli: use a crowdin already on PATH instead of downloading.
    • npm_registry_url: download from an npm mirror instead of the public registry.
  • Port of entrypoint.sh: the shell script is rewritten in TypeScript using @actions/core and @actions/exec. Pull requests, labels, assignees and reviewers now go through Octokit instead of curl and jq. Branch handling, restoring the original checkout and GPG signing behave as before.
  • No global state on the runner: the commit name, email and signing key are passed to the commit command with git -c. The GPG key is imported into a temporary GNUPGHOME, which is deleted afterwards. This matters on self-hosted runners, where the old global git config changes would persist.
  • user input: deprecated and has no effect, because files are now created by the runner user.
  • CI: unit tests (vitest) and a check that dist/ is up to date. The action itself is run on ubuntu-latest, ubuntu-24.04-arm, macos-latest, macos-15-intel and windows-latest. v4 is added to update-main-version.yml.
  • Docs: the README has a "Upgrading to v4" section and documents the CLI installation options. CONTRIBUTING.md has development instructions.

Behavior changes (why this is a breaking release)

  • The action runs on the runner itself, not in a container. git must be available on the runner, and gpg only when gpg_private_key is set.
  • Arguments in command, command_args and *_args are split the way a shell would, so --label "a b" is passed as one argument. Before, the quotes were passed through literally.
  • pull_request_url no longer has surrounding double quotes. This was a bug in the old script.
  • If adding labels, assignees or reviewers fails, the action logs a warning and continues. The old script ignored these errors silently.

Testing

  • npm run typecheck, npm test (37 tests) and npm run build pass locally.
  • The git tests run against a real local repository and bare remote. One of them creates a signed commit with a freshly generated GPG key.
  • I ran the bundled dist/index.js locally on macOS arm64. Downloading, verifying and caching the CLI, reusing the cached copy, cli_version: latest, use_installed_cli and the command_output output all worked.

Notes for maintainers

  • I left the @v3 references in the README and docs unchanged; switching them to @v4 is a release decision.
  • dist/ is committed and marked as linguist-generated.

🤖 Generated by Claude Opus 5.5 (claude-opus-5.5)

@andrii-bodnar

Copy link
Copy Markdown
Member

Thanks for this, @minijus! We'd like to try this approach before committing to it, so here's the plan:

  • I've retargeted this PR to a new js-action branch.
  • After merging, we'll publish pre-releases from that branch (e.g. v4.0.0-beta.1, …), so people on macOS/Windows/arm64 or Kubernetes-hosted runners can try it.
  • We'll run it for some time. v3 (Docker) stays the default and keeps getting fixes. After that we'll decide on the long-term direction.

Before we merge, could you:

  1. Rebase onto js-action (keep the entrypoint.sh deletion).
  2. Port the LFS fix from fix: push Git LFS objects before pushing the localization branch #324 to src/git.ts: run git lfs push before the --no-verify push when the commit contains LFS files. Otherwise the rewrite would bring Failure on git push with LFS #323 back.

Once that's done, I'll approve the CI run so the full OS matrix runs. Thank you!

Replace the Docker container action (Dockerfile + entrypoint.sh) with a
TypeScript action running on node24, bundled into dist/index.js.

- Install the native Crowdin CLI binary for the runner platform from the
  @crowdin/cli-<platform> npm packages, verify its integrity and cache it
  with @actions/tool-cache. New inputs: cli_version, use_installed_cli,
  npm_registry_url.
- Port entrypoint.sh to TypeScript using @actions/core, @actions/exec and
  Octokit (pull request, labels, assignees, reviewers).
- Keep all existing inputs and outputs. The `user` input is deprecated and
  has no effect, as files are now created by the runner user.
- Pass the git identity and signing key per command and import the GPG key
  into a temporary GNUPGHOME instead of modifying global configuration.

Works on Linux, macOS and Windows runners (x64/arm64) without Docker.

Closes crowdin#321
Refs crowdin#160, crowdin#284

BREAKING CHANGE: the action now runs on the runner host instead of a
Docker container, requires git on the runner (and gpg when signing), and
the pull_request_url output no longer includes surrounding quotes.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@minijus
minijus force-pushed the feat/node24-action branch from 9c6f371 to 5589379 Compare November 3, 2026 04:12
@minijus

minijus commented Nov 3, 2026

Copy link
Copy Markdown
Author

@andrii-bodnar Done. I rebased the PR onto js-action and kept the entrypoint.sh deletion. In src/git.ts, the action now checks for tracked LFS files and runs git lfs push before the git push --no-verify; if the LFS upload fails, it stops before pushing the branch. I also kept the LFS example from #324 and added tests for the upload order, LFS upload failure, and repositories without LFS.

Validation passed locally under Node 24: type-check, all 42 tests, and the bundle build. The updated GitHub test workflow is awaiting approval.

🤖 Generated by GPT-6 Luna (gpt-6-luna)

@andrii-bodnar andrii-bodnar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@minijus thank you!

@andrii-bodnar
andrii-bodnar merged commit f1b2bc3 into crowdin:js-action Nov 3, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Convert the action from a Docker container action to a JavaScript (node24) action now that CLI v5 is a native binary

2 participants