Автоматизация процесса сборки и публикации с помощью действий GitHub (и реестра пакетов GitHub) - PullRequest
0 голосов
/ 11 октября 2019

Это вопросы и ответы, я поставил свое решение в ответах.

Я участвую как в бета-версии GitHub Actions, так и в GitHub Package Registry. Поскольку я очень ленивый человек, я не только автоматизировал процесс сборки своего пакета npm, но я также хотел автоматизировать его публикацию.
Для этого мне пришлось столкнуться с некоторыми проблемами:

  1. Как я могу убедиться, что задание "публикация" выполняется в только что собранной версии?
  2. Как определить, когда версия пакета обновляется в действиях GitHub?
  3. Как я могу использовать результат этой проверки для редактирования поведения рабочего процесса Actions?
  4. Как я могу опубликовать пакет в npm из рабочего процесса?
  5. Как я могупосле публикации в npm опубликовать ту же самую точную версию в реестре пакетов GitHub?

1 Ответ

0 голосов
/ 11 октября 2019

Примечание: результат всех этих шагов можно найти здесь , в файле рабочего процесса, который я фактически использовал для своего пакета.

1. Убедиться в том, что задание «публикация» будет выполнено в только что собранной версии

Самый простой способ, который я нашел, это просто поместить два задания в один и тот же рабочий процесс и запускать их оба на каждом * 1009. * событие: задание публикации было ограничено для выполнения только в ветке master и после первой.

  • Задание сборки:

Необходимо построить новую версию пакета, затем зафиксировать в хранилище: фиксация имеет решающее значение, поскольку это позволяет другой работе выбрать собранную версию. Чтобы зафиксировать изменения, внесенные в прогоне рабочего процесса, вы можете использовать одно из моих действий add-and-commit: оно будет загружать изменения в репозиторий GitHub с помощью «поддельного» пользователя git.
Ваш рабочий процессзадание должно выглядеть примерно так:

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest

    steps: 
    - name: Checkout repository
      uses: actions/checkout@v1.0.0

    - name: Set up Node.js
      uses: actions/setup-node@v1.2.0
      with:
        node-version: '10.x'

    - name: Install dependencies
      run: npm install

    - name: Compile build
      run: npm run build # This can be whatever command you use to build your package

    - name: Commit changes
      uses: EndBug/add-and-commit@v2.1.0
      with: # More info about the arguments on the action page
        author_name: Displayed name
        author_email: Displayed email
        message: "Message for the commit"
        path: local/path/to/built/version
        pattern: "*.js" # Pattern that matches the files to commit
        force: true # Whether to use the --force flag
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This gets generated automatically
  • Опубликовать задание:

Мы хотим, чтобы оно запускалось только в ветви master послеbuild завершено, поэтому мы можем установить его следующим образом:

publish:
  name: Publish to NPM & GitHub Package Registry
  runs-on: ubuntu-latest
  if: contains(github.ref, 'master') # This sets the branch
  needs: build # This makes it wait for the build job

2. Обнаружение изменения версии

Я не нашел хорошего способа сделать это, поэтому я сделал другое действие, version-check: это действие сканирует коммиты каждого нажатия и пытается выяснитьвключают ли они изменение версии.
Вам необходимо настроить эти два шага:

steps:
- name: Checkout repository
  uses: actions/checkout@v1.0.0
  with:
    ref: master

- name: Check version changes
  uses: EndBug/version-check@v1.0.0 # More info about the arguments on the action page
  id: check # This will be the reference for later

3. Использование результатов проверки для редактирования поведения рабочего процесса

version-check обеспечивает два выхода: changed (было ли обновление) и type (типof update, например "patch", "minor", ...).
К этим выходам можно получить доступ через контекст steps , и вы можете использовать их, чтобы решить, следует ли выполнить шаг илинет, используя if свойство . Это пример:

# check is the id we gave to the check step in the previous paragraph
- name: Version update detected
  if: steps.check.outputs.changed == 'true'
  run: 'echo "Version change! -> ${{ steps.check.outputs.type }}"'

4. Публикация пакета в NPM

Публикация пакета в NPM довольно проста: вам нужно только настроить Node.js, а затем использовать npm publish, как на своем собственном компьютере. Единственное отличие состоит в том, что для аутентификации вам понадобится токен: вы можете создать его на npmjs.com . После того, как вы его создали, НЕ помещайте его в сам рабочий процесс: вы можете сохранить его как «секрет», вы можете найти больше информации о них здесь .
В этом примере я буду считать, что вашсекрет называется NPM_TOKEN:

- name: Set up Node.js for NPM
  if: steps.check.outputs.changed == 'true'
  uses: actions/setup-node@v1.2.0
  with:
    registry-url: 'https://registry.npmjs.org' # This is just the default registry URL

- name: Install dependencies
  if: steps.check.outputs.changed == 'true'
  run: npm install

- name: Publish the package to NPM
  if: steps.check.outputs.changed == 'true'
  run: npm publish
  env:
    NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # NPM will automatically authenticate with this

5. Публикация пакета в реестре пакетов GitHub

На данный момент работать с реестром пакетов GitHub не очень приятно, если вы хотите продолжать публиковать свой существующий пакет в npm: вот почему он требует, чтобы пакеты были ограничены, и этоможет испортить ситуацию (ваш пакет не может быть ограничен или может находиться под другим именем).
Я обнаружил, что самый простой способ справиться с этим - это обходной путь:

  • в вашем рабочем процессепереустановите Node.js, но добавьте URL-адрес реестра GPR и область имен
  • Создайте сценарий npm, который редактирует ваш package.json, чтобы он изменил исходное имя пакета на то, которое вам нужно опубликоватьв GPR (включая объем)
  • После вызова этого сценария в рабочем процессе используйте npm publish, как и раньше, но на этот раз, используя встроенный GITHUB_TOKEN как NODE_AUTH_TOKEN.
{
  "name": "YourPackageName",
  ...
  "scripts": {
    "gpr-setup": "node scripts/gpr.js"
  }
}
// scripts/gpr.js

const fs = require('fs')
const { join } = require('path')

// Get the package obejct and change the name
const pkg = require('../package.json')
pkg.name = '@yourscope/YourPackageName'

// Update package.json with the udpated name
fs.writeFileSync(join(__dirname, '../package.json'), JSON.stringify(pkg))
- name: Set up Node.js for GPR
  if: steps.check.outputs.changed == 'true'
  uses: actions/setup-node@v1.2.0
  with:
    registry-url: 'https://npm.pkg.github.com/'
    scope: '@endbug'

- name: Set up the package for GPR
  if: steps.check.outputs.changed == 'true'
  run: npm run gpr-setup

- name: Publish the package to GPR
  if: steps.check.outputs.changed == 'true'
  run: npm publish
  env:
    NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Результат

Ваш пакет теперь опубликован как в NPM, так и в GPR (хотя описание необходимо добавить в GPR вручную). Вы можете найти все, что я имею в виду в версии uptime-монитора 4.0.3:

...