Nx monorepo의 npm 패키지 관리 및 GiitHub Actions

처음 뵙겠습니다.이 글은 Classi Advent Calendar 202012/5 담당자의 글입니다.
본고는 Nx와 GiitHub Actions의monorepo의 CI/CD 구축에 대해 누구에게 도움이 될 수 있는 Tips와 남의 도움을 바라는 실패 경험을 간단하게 요약한다.
  • nrwl/nx: Extensible Dev Tools for Monorepos
  • npm package monorepo 관리


    이번에는 하나의 창고로 여러 npm 패키지의 개발을 관리하기 위해 Nx를 사용합니다.
    레나를 사용하는 옵션도 있지만, 관리하고 싶은 것이 Anglar 애플리케이션 라이브러리여서 친화력 높은 Nx를 적용했다.
    # ワークスペースの作成
    $ npx create-nx-workspace my-awesome-libs --preset oss --no-nx-cloud
    $ cd libs-monorepo
    # ライブラリプロジェクトの追加
    $ yarn add -D @nrwl/angular
    $ yarn nx generate @nrwl/angular:library --name=foo --publishable
    
    이 점은 공식 문서에서 이미 충분하다. 다음은 실제 운용에 공을 들인 부분을 소개한다.

    CHANGELOG.관리md


    이번에 각 라이브러리는 독립적으로 버전 관리와 공개를 진행한다.(Lerna에서 말하는 independent 모드)
    따라서 stardard-version 생성된 CHANGELOG.md도 모든 프로그램 라이브러리에 독립된다.

    .versionrc 파일 구성


    각 항목의 루트 디렉터리 README.md 와 같은 층) 에서standard-version용 설정 파일을 만듭니다.path는 이 역할 영역CHANGELOG.md에서만 지정한 디렉터리 내부 파일의 제출을 수정한 설정을 포함한다.tag-prefix는 프로젝트의 개별 CI/CD를 진행할 때 각 프로그램 라이브러리의 발행을 구별하기 위한 중요한 설정 항목이다.
    packages/foo/.versionrc
    {
      "path": ".",
      "tag-prefix": "foo-lib-v",
      "releaseCommitMessageFormat": "chore(release): foo-lib@{{currentTag}}"
    }
    

    nx release--project = foo 설정


    나는 이 절차에 또 다른 방법이 있다고 생각하지만, 이미 표준-version이 Nx의 빌딩을 통해 실행할 수 있도록 설정되어 있다.@nrwl/workspace:run-commands 컴파일러는 Nx를 통해 임의의 명령을 실행할 수 있습니다.npx standard-version packages/foo 디렉터리에서 명령을 실행하여 방금 추가된 .versionrc 파일에 따라 CHANGELOG.md 생성합니다.
    다음 설정workspace.json과 같이 다음 명령을 통해 생성할 수 있습니다CHANGELOG.md.
    $ yarn nx run foo:release --dry-run
    # あるいは
    $ yarn nx release foo --dry-run
    
    workspace.json
    {
      "version": 1,
      "projects": {
        "foo": {
          "projectType": "library",
          "root": "packages/foo",
          "sourceRoot": "packages/foo/src",
          "prefix": "foo",
          "architect": {
            //...
            "release": {
              "builder": "@nrwl/workspace:run-commands",
              "options": {
                "command": "npx standard-version",
                "cwd": "packages/foo",
                "parallels": false
              }
            }
          }
        }
      }
    }
    
    이렇게 하면 라이브러리 항목의 개별적인 시간에 임의로 제출할 때 시험 운행을 할 수 있다.

    GiitHub Action의 자동 게시


    표준-version의bajoning[email protected]과 같은 형식의 Giit 라벨이 부여되어 촉발용 GiitHub Actions로 npm에 자동publish를 진행하기 때문이다.

    탭 트리거의 작업 흐름 정의


    이름이 .github/workflows/publish-latest.yml인 GiitHub Actions의 워크플로 파일에는 다음과 같습니다.
    워크플로우 트리거는 push/tags 파일에 설정된 .versionrc와 일치하도록 태그 이름을 지정하는 모드를 사용합니다.
    여러 개의 포장이 되면 이 패턴이 늘어난다.
    name: publish (latest)
    
    on:
      push:
        tags:
          - foo-lib-v*
          - bar-lib-v*
    
    jobs:
      publish-latest:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v2
    

    어떤 탭이 터치했는지 얻기


    이런 방법에서foo-lib을 발표할 때와bar-lib를 발표할 때 같은 동작을 수행하기 때문에 어떤 탭에 의해 촉발되는 선택적인publish를 얻을 필요가 있다.
    GiitHub Actions에서 탭이 시작하는 작업흐름tag-prefix을 트리거하는 환경 변수는 탭에 대한 참조이기 때문에 여기서 얻을 수 있습니다.
    다음 기능GITHUB_REF을 사용하여 다음 작업에서 환경 변수에서 얻은 탭 이름을 사용할 수 있습니다.
    jobs:
      publish-latest:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v2
          # == region variables
          - run: echo "::set-output name=result::${GITHUB_REF/refs\/tags\//}"
            id: targetTag
          - run: echo "targetTag:${{steps.targetTag.outputs.result}}"
          # == endregion
    
    

    : set-output 선택적 구축 /publish


    그리고 탭 이름이 어떤 프로그램 라이브러리 항목을 만들고publish를 하는지 제어하기만 하면 됩니다.
    GiitHub Actions는 작업 내if 필드가 있으며, 표현식 평가 결과if에 대해서만 수행됩니다.true시 다음 퀘스트에 들어갑니다.false에 삽입된 if 함수를 사용하여 탭 이름이 모든 프로그램 라이브러리의prefix에서 시작되는지 검사합니다.
    프로그램 라이브러리가 증가함에 따라 yml 파일도 연장 과제가 있지만 무한히 증가하는 것은 아니다. 복잡한 조개 스크립트를 직접 쓰지 않으면 복잡해지지 않는다.
          # scoped packageをpublishするために必要な設定。GitHub Actionsのドキュメントを参照。
          - uses: actions/setup-node@v1
            with:
              node-version: 12.x
              registry-url: 'https://registry.npmjs.org'
              scope: '@classi'
          - run: yarn install
    
          - name: publish foo
            if: ${{ startsWith(steps.targetTag.outputs.result, 'foo-lib-v') }}
            run: ./tools/scripts/publish-latest.sh "foo"
            env:
              NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
          - name: publish bar
            if: ${{ startsWith(steps.targetTag.outputs.result, 'bar-lib-v') }}
            run: ./tools/scripts/publish-latest.sh "bar"
            env:
              NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
    
    실제publish 처리는 다음과 같은 간단한 스크립트입니다.신중하게 사용can-npm-publish하여 버전이 중복되지 않았는지 확인한 후 퍼블릭을 진행한다.
    tools/scripts/publish-latest.sh
    #!/bin/bash -eux
    
    project=$1
    
    echo "Publishing ${project}"
    
    yarn build ${project} --prod --with-deps
    yarn can-npm-publish dist/packages/${project} && yarn --cwd dist/packages/${project} publish --access public
    
    echo "Done"
    

    진행 불순: 지점 제한


    지금은 상술한 업무 절차와 기본적으로 같은 것을 운용하고 있지만 실제로는 하고 싶은 일이 하나 더 있다.
    GiitHub ActionsstartsWith 트리거에서 태그 커밋과 일치하면 모든 분기의 커밋이 트리거됩니다.
    나는 이것을'push/tagspush에서 지점의 제출처에 발행 라벨이 붙었을 때'의 복합 조건으로 삼고 싶었지만 상당히 격렬한 격투 끝에 포기했다.
    중도에 순조롭게 진행될 것으로 예상되는 방법은 동작main 지령을 사용하는 것이다.이 명령은 제출한 지점 목록을 가져오고 git branch --containspush/tags 에서 지점을 검사하고 포함할 수 있는지 확인하도록 합니다. GITHUB_SHA
          - uses: actions/checkout@v2
          - run: git fetch origin main
          # == region variables
          - run: echo "::set-output name=result::$(git branch -r --contains ${GITHUB_SHA} --format "%(refname:lstrip=2)" | grep "main")"
            id: validBranch
          - run: echo "::set-output name=result::${GITHUB_REF/refs\/tags\//}"
            id: targetTag
          - run: echo "validBranch:${{steps.validBranch.outputs.result==true}}"
          - run: echo "targetTag:${{steps.targetTag.outputs.result}}"
          # == endregion
    
    현지에서 시행되면 순조롭게 진행될 것으로 보이지만, 지티허브 액션에서는 순조롭지 않아 어떤 지점에도 포함되지 않는 제출이 됐다.
    나는 원인main이 체크아웃할 때 HEAD를 만질 것 같고actions/checkout@v2에 옵션을 더해서 상대방이 원격 지점을 조사하도록 해도 안 된다고 생각해서 마침내 몰랐다.
    순조롭게 진행되는 방법을 아는 사람이 있다면 저에게 알려주세요.

    총결산

  • Nx로 라이브러리monorepo를 제작하고 independent 모드로 관리하면
  • standard-version 생성 라이브러리 개별-r을 사용하면
  • GiitHub Actions를 사용하여 모든 라이브러리를 자동으로 공개할 수 있다면
  • 탭이 터치하는 동작에서 지점을 어떻게 제한하는지 몰라
  • 12/6은onigra가 뭐라고 쓴 것 같은데.기대해주세요!
    Classi Advent Calendar 2020 - Qiita

    좋은 웹페이지 즐겨찾기