Невозможно выполнять команды git удаленно из скрипта

У меня есть сценарий, который я хочу запустить при объединении запроса на включение в GitHub. Скрипт написан на JavaScript с использованием библиотеки ZX.

Цель скрипта — автоматически определить следующую версию пакета, который будет опубликован в npm, и действия, включая получение последних тегов git из GitHub, чтобы договориться, под какой версией выпустить.

К сожалению, мне очень сложно выполнить простое git pull --tags действие. Мне удалось установить act, который позволяет мне запускать скрипт локально.

Когда скрипт достигает шага, на котором он извлекает данные из git, время ожидания истекает. Сообщение об ошибке не очень понятно, но я вижу что-то с «Именем пользователя», поэтому подозреваю, что он пытается пройти аутентификацию с помощью GitHub, используя пароль вместо токена личного доступа:

| 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.

Это мой рабочий процесс:

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 [email protected]:
          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

Изначально вместо prepublish.js в последней строке я набрал:

  run: git pull --tags

И какое-то время это работало, пока я не внес какое-то изменение, которого не помню, а теперь оно также терпит неудачу, если я извлекаю его непосредственно из рабочего процесса.

Внутри prepublish.js Пробовал разное:

  • Я попробовал распечатать GITHUB_TOKEN. Оно работает.

  • Я пробовал вызывать команды git, которые не требуют аутентификации, с помощью удаленного репозитория, например git status, и все работает нормально.

  • Я попробовал запустить git config --list и распечатать результат. Интересно, что я заметил, что токен не включается в выходные данные. Я не уверен, есть ли в GitHub какая-то логика для удаления конфиденциальных токенов перед печатью, но я попытался удалить строку x-access-token из рабочего процесса и вместо этого запустить ее внутри prepublish.js вот так:

    await $`git config --global url.https://x-access-token:${process.env.GITHUB_TOKEN}@github.com/.insteadOf https://github.com/`;
    

    Последующая печать конфигурации git действительно включает токен в URL-адрес, но вызовы git push по-прежнему завершаются с той же ошибкой, и я не могу придумать никаких других шагов, которые можно было бы попробовать на данный момент.

Вот что у меня сейчас есть 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.info({ gitConfig });

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

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

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

  return;
})()

Не уверен, что понимаю: «Цель сценария — автоматически определить следующую версию пакета, который будет опубликован в npm»? Разве не для этого нужны npm version major, npm verison minor и npm version patch? Вы запускаете их, нажимаете на главную с помощью --tags, затем запускаете npm publish. Потому что единственная «свобода» заключается в том, какая из этих троих будет нарушена, и я не вижу в вашем сценарии ничего, что бы это проверяло (а это означает, что можно с уверенностью предположить, что вы нарушаете semver atm, и в этом случае просто продолжайте нарушать это). но используя обычные команды npm?)

Mike 'Pomax' Kamermans 25.06.2024 19:52

В настоящее время я пропустил эту часть сценария, чтобы сосредоточиться на работе команд git. Я использую npm version, чтобы установить фактическую версию, но это специальный скрипт, который должен определить, является ли это версией patch, minor или major`.

zkwsk 25.06.2024 20:08

Такое ощущение, что можно было бы выиграть от «не использования специального решения» и вместо использования JS-версии Octokit, чтобы вы могли общаться с github «обычным» способом? (например, docs.github.com/en/rest/guides/…, где даже описано, как интегрироваться с действиями github)

Mike 'Pomax' Kamermans 25.06.2024 20:30

Вы правы, я мог бы использовать Octokit для получения метаданных, таких как теги. Но после запуска npm version я все равно застрял бы, потому что все равно не смог бы запустить git push --tags и отправить новую версию на пульт.

zkwsk 25.06.2024 20:46

Как упоминалось в вопросе выше, я сталкиваюсь с той же проблемой, если пытаюсь запустить команды git непосредственно в действии github, а не в файле javascript. Я уже написал полный сценарий, который работает в локальной среде, поэтому я бы предпочел использовать его повторно. Но я понимаю, что мне может понадобиться другой подход к моему рабочему процессу действий Github, но ничего не будет работать, если я не смогу вытащить и отправить в git.

zkwsk 25.06.2024 20:49

Верно, но я хочу сказать, что ваш скрипт использует голую https-аутентификацию имени пользователя:пароля вместо «правильной» аутентификации API. В журнале, который вы показываете, git сообщает вам, что вам необходимо войти в систему в интерактивном режиме, поскольку URL-адрес в вашем пользовательском скрипте этого не делает. То, с чем вы не столкнетесь при использовании официальной библиотеки API.

Mike 'Pomax' Kamermans 25.06.2024 21:02

Хорошо, я не осознавал, что именно это означает вывод, но это имеет смысл. Но каков тогда «нормальный» способ аутентификации команд git (а не вызовов API) в рабочем процессе действий Github? Я не думаю, что смогу использовать Octokit для создания команды git push --tags?

zkwsk 25.06.2024 21:25

Хорошо, у меня был некоторый прогресс. Вместо того, чтобы переписывать URL-адрес, я смог повторно добавить пульт с аутентификацией по токену: git remote remove origingit remote add org https://<user>:<token>@github.com/<org>/<repo>.git После этого я смог git pull --tags. К сожалению, я не могу прочитать токен из .env с помощью ${{ secrets.GITHUB_TOKEN }}, и мне пришлось жестко запрограммировать токен, что явно невозможно. Однако GITHUB_TOKEN доступен в моем javascript.

zkwsk 25.06.2024 21:57

Что вы имеете в виду под «Я не могу прочитать токен из .env»? Действия Guthub используют секреты github вашего проекта, а не файлы .env (см. docs.github.com/en/actions/security-guides/…)

Mike 'Pomax' Kamermans 25.06.2024 22:18

Я тестирую рабочий процесс локально с помощью act и для этой цели добавил файл .env. Я нашел решение. См. ниже.

zkwsk 25.06.2024 22:38

Ах, мои извинения, я пропустил ту часть, где вы тестировали act: с первого дня это страдало от того, что было «похоже», но на самом деле не «то же самое, что» реальные действия github.

Mike 'Pomax' Kamermans 25.06.2024 22:40
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
11
73
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мне удалось найти решение самостоятельно.

Во-первых, я неправильно ссылался на переменную среды GITHUB_TOKEN в разделе запуска. Вместо ${{ secrets.GITHUB_TOKEN }} мне нужно было использовать ${{ env.GITHUB_TOKEN }}.

Во-вторых, вместо переписывания URL-адресов мне нужно было заново добавить пульт с правильным форматом URL-адресов:

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

В итоге мой рабочий процесс стал выглядеть так:

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

Внутри prepublish.js теперь я могу выполнять команды git:

...
const version = ...

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

Другие вопросы по теме