node.jsgitgithub-actionsact

Unable to perform git commands on remote from within script


I have script I want to run upon merging a pull request in GitHub. The script is written in JavaScript using the ZX library.

The purpose of the script is to automatically determine the next version of a package to be published to npm and the actions including fetching the latest git tags from GitHub in order to negotiate what version to release under.

Unfortunately I'm struggling a lot with running a simple git pull --tags action. I managed to install act which enables me to run the script locally.

When the script reaches the step where it pulls from git it times out. The error message is not very clear, but I see something with "Username" so I suspect it is trying to authenticate with GitHub using password instead of personal access token:

| Username for 'https://github.com': /Users/work/projects/aves/node_modules/zx/build/core.cjs:245
|             const output = new ProcessOutput(
|                            ^
| 
| ProcessOutput [Error]: 
|     at /Users/work/projects/aves/scripts/prepublish.js:609:37
|     exit code: null
|     signal: SIGTERM
|     at EventEmitter.end (/Users/work/projects/aves/node_modules/zx/build/core.cjs:245:28)
|     at EventEmitter.emit (node:events:519:28)
|     at ChildProcess.<anonymous> (/Users/work/projects/aves/node_modules/zx/build/vendor.cjs:20283:16)
|     at ChildProcess.emit (node:events:519:28)
|     at maybeClose (node:internal/child_process:1105:16)
|     at Socket.<anonymous> (node:internal/child_process:457:11)
|     at Socket.emit (node:events:519:28)
|     at Pipe.<anonymous> (node:net:338:12) {
|   _code: null,
|   _signal: 'SIGTERM',
|   _stdout: '',
|   _stderr: '',
|   _combined: ''
| }
| 
| Node.js v20.15.0
error Command failed with exit code 1.

This is my workflow:

name: Publish Package to npmjs
on:
  pull_request:
    branches:
      - main
    types: ['closed']
jobs:
  build:
    runs-on: ubuntu-latest
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - name: Git checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Setup Node.js and copy .npmrc file
        uses: actions/setup-node@v4
        with:
          node-version: '20.x'
          registry-url: 'https://registry.npmjs.org'
      - name: Configure git for HTTPS
        run: |
          git config --global url.https://github.com/.insteadOf git@github.com:
          git config --global url.https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/.insteadOf https://github.com/
      - name: Fetch tags
        run: yarn && yarn zx ./scripts/prepublish.js --ci

Initially, instead of running prepublish.js on the last line I ran:

  run: git pull --tags

And it used to work for a short while until I made some change I don't remember and now it also fails if I pull directly from the workflow.

Inside prepublish.js I tried various things:

Here is what I currently have in prepublish.js

#!/usr/bin/env zx

const zx = require('zx');

const { $, spinner } = zx;

(async () => {
  await $`git config --global url.https://x-access-token:${process.env.GITHUB_TOKEN}@github.com/.insteadOf https://github.com/`;
  const { stdout: gitConfig } = await $`git config --list`;

  console.log({ gitConfig });

  const { stdout, stderr } = await $`git pull --tags`.timeout('2m');

  if (stderr) {
    console.error('stderr:', stderr);
  }

  console.log('stdout:', stdout);

  return;
})()

Solution

  • I managed to find a solution myself.

    First, I was referencing the environment variable for GITHUB_TOKEN wrong in the run section. Instead of ${{ secrets.GITHUB_TOKEN }} I needed to use ${{ env.GITHUB_TOKEN }}.

    Second, instead of rewriting URLs I needed to re-add the remote with the correct URL format:

    git remote remove origin
    git remote add org https://<user>:${{ env.GITHUB_TOKEN }}@github.com/<organisation>/<repo>.git
    

    So eventually my workflow ended up looking like this:

    name: Publish Package to npmjs
    on:
      pull_request:
        branches:
          - main
        types: ['closed']
    jobs:
      build:
        runs-on: ubuntu-latest
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        steps:
          - name: Git checkout
            uses: actions/checkout@v4
          - name: Setup Node.js and copy .npmrc file
            uses: actions/setup-node@v4
            with:
              node-version: '20.x'
              registry-url: 'https://registry.npmjs.org'
          - name: Configure git for HTTPS
            run: |
              git remote remove origin
              git remote add org https://GITHUB_ACTIONS_BOT:${{ env.GITHUB_TOKEN }}@github.com/<org>/<repo>.git
          - name: Fetch tags
            run: yarn && yarn zx ./scripts/prepublish.js --ci
    
    

    Within prepublish.js I'm now able to execute git commands:

    ...
    const version = ...
    
    await $`npm version ${version}`
    await $`git push --tags`
    ...