[Flutter] pub.dev 배포 자동화

[Flutter] pub.dev 배포 자동화

2023-08-31 hit count image

Flutter용으로 개발한 패키지를 GitHub Actions를 사용하여 pub.dev 배포를 자동화하는 방법에 대해서 알아보도록 하겠습니다.

개요

Flutter로 앱을 개발하다보면, 공통 라이브러리 또는 오픈소스화를 위해 패키지(Package)를 만들어서 https://pub.dev/에 배포해야할 때가 있습니다.

이전 블로그 포스트에서는 Flutter에 필요한 패키지를 제작하고 pub.dev에 배포하는 방법에 대해서 알아보았습니다.

이번 블로그 포스트에서는 pub.dev에 배포된 패키지를 GitHub Actions를 사용하여 자동으로 pub.dev에 배포하는 방법에 대해서 알아보도록 하겠습니다.

Automated publishing 활성화

pub.dev에 배포된 패키지를 GitHub Actions를 사용하여 자동으로 배포하기 위해서는 pub.dev에서 Automated publishing 옵션을 활성화할 필요가 있습니다.

브라우저에서 https://pub.dev/ 페이지를 열고, 배포 자동화를 하고자 하는 패키지의 페이지로 이동합니다.

Automate publishing package - pub.dev package page

자신이 소유하고 있는 패키지라면 상단에 AdminActivity log 탭이 활성화된 것을 확인할 수 있습니다. 이제 Admin 탭을 선택하여 관리자 페이지로 이동합니다.

Automate publishing package - automated publishing option

관리자 페이지에서 스크롤하여 하단으로 이동하면 Automated publishing 옵션을 확인할 수 있습니다. Enable publishing from GitHub Actions를 선택하여 옵션을 활성화시킵니다.

그런 다음 Repository에 해당 패키지의 코드를 저장하고 있는 GitHub의 저장소를 owner/repository 형식으로 입력합니다.

저는 다음과 같은 패키지를 가지고 있습니다.

따라서 Repository에는 dev-yakuza/bull을 입력하였습니다.

그런 다음, 배포에 사용할 Git Tag 형식을 지정합니다. 보통은 패키지를 배포할 때 v2.5.7과 같은 형태의 Git Tag를 사용합니다. 따라서 특별한 이유가 없다면 해당 태그를 그대로 사용합니다.

GitHub Actions 작성

GitHub Actions를 사용하여 pub.dev에 패키지를 자동으로 배포할 준비가 되었습니다. 이제 Example workflow를 참고하여 GitHub Actions를 제작할 필요가 있습니다.

Automate publishing package - GitHub Actions example workflow

또는 다음 링크를 참고하여 작성할 수 있습니다.

저는 .github/workflows/release.yml 파일을 생성하고 다음과 같이 GitHub Actiosn를 작성하여 사용하였습니다.

name: Release

on:
  push:
    tags:
      - 'v[0-9]+.[0-9]+.[0-9]+'

jobs:
  release:
    permissions:
      contents: write
      pull-requests: write
      id-token: write
    runs-on: ubuntu-latest
    steps:
      - name: Get semantic version
        id: semver
        run: echo "::set-output name=version::${GITHUB_REF#refs/tags/v}"

      - uses: actions/checkout@v3
        with:
          ref: v$

      # For Flutter package
      - uses: dart-lang/setup-dart@v1
      - uses: subosito/[email protected]
        with:
          flutter-version: '3.7.12'
      - name: Install dependencies
        run: flutter pub get

      - name: Publish
        run: flutter pub publish --force

      # For Dart package
      # - uses: dart-lang/setup-dart@v1
      # - name: Install dependencies
      #   run: dart pub get
      # - name: Publish
      #   run: dart pub publish --force

이와 같이 작성한 GitHub Actions는 다음 명령어를 사용하여 실행할 수 있습니다.

git tag v2.5.7
git push origin v2.5.7

문제점

이전 블로그에서도 설명하였지만, 패키지를 pub.dev에 배포하기 위해서는 CHANGELOG.md 파일과 pubspec.yaml 파일에 version이 일치해야 하며, pub.dev에 배포되지 않은 버전을 사용해야 합니다.

CHANGELOG.md 파일과 pubspec.yaml 파일의 버전 내용을 수정하고 GitHub에 커밋을 한 후, Git Tag 명령어로 pub.dev에 배포할 수 있습니다. 하지만 이는 100% 자동화라고 볼 수 없습니다.

Changelog 자동화

이 문제를 해결하기 위해서는 GitHubRelease note를 자동화하고 CHANGELOG.md 파일을 자동으로 업데이트시킬 필요가 있습니다. GitHub Actions를 사용하여 Release noteCHANGELOG.md 파일의 업데이트를 자동화하는 방법에 대해서는 다음 링크를 참고하시 바랍니다.

위에 링크를 참고하여 Release noteCHANGELOG.md 파일을 자동화할 수 있습니다. 저는 CHANGELOG.md 파일의 자동화는 다음과 같이 .github/workflows/release.yml 파일을 수정하여 사용하고 있습니다.


name: Release

on:
  push:
    tags:
      - 'v[0-9]+.[0-9]+.[0-9]+'

jobs:
  release:
    permissions:
      contents: write
      pull-requests: write
      id-token: write
    runs-on: ubuntu-latest
    steps:
      - name: Get semantic version
        id: semver
        run: echo "::set-output name=version::${GITHUB_REF#refs/tags/v}"

      - uses: actions/checkout@v3
        with:
          ref: v${{ steps.semver.outputs.version }}

      - uses: release-drafter/release-drafter@v5
        id: target_release_notes
        with:
          tag: ${{ steps.semver.outputs.version }}
          name: ${{ steps.semver.outputs.version }}
          version: ${{ steps.semver.outputs.version }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Update Changelog
        uses: stefanzweifel/changelog-updater-action@v1
        with:
          latest-version: ${{ steps.target_release_notes.outputs.tag_name }}
          release-notes: ${{ steps.target_release_notes.outputs.body }}

      - name: Commit updated Changelog
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: 'docs: Update changelog'
          file_pattern: CHANGELOG.md
          branch: main

      - uses: dart-lang/setup-dart@v1
      - uses: subosito/[email protected]
        with:
          flutter-version: '3.7.12'
      - name: Install dependencies
        run: flutter pub get

      - name: Update version
        run: dart run bull pub_version --version=${{ steps.semver.outputs.version }}

      - name: Commit updated pubspec
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: 'chore: Update version for release'
          file_pattern: pubspec.yaml
          branch: main

      - name: Update Git tag
        run: |
          git tag ${{ github.ref_name }} -f
          git push origin ${{ github.ref_name }} -f

      - uses: release-drafter/release-drafter@v5
        with:
          tag: ${{ steps.semver.outputs.version }}
          name: ${{ steps.semver.outputs.version }}
          version: ${{ steps.semver.outputs.version }}
          publish: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Publish
        run: flutter pub publish --force

pubspec.yaml의 version 업데이트

pubspec.yamlversion을 업데이트하기 위해 Bull 패키지를 사용하고 있습니다.

다음 명령어를 사용하여 Bull 패키지를 설치합니다.

dart pub add --dev bull

그런 다음, .github/workflows/release.yml 파일을 다음과 같이 수정합니다.


name: Release

on:
  push:
    tags:
      - 'v[0-9]+.[0-9]+.[0-9]+'

jobs:
  release:
    permissions:
      contents: write
      pull-requests: write
      id-token: write
    runs-on: ubuntu-latest
    steps:
      - name: Get semantic version
        id: semver
        run: echo "::set-output name=version::${GITHUB_REF#refs/tags/v}"

      - uses: actions/checkout@v3
        with:
          ref: v${{ steps.semver.outputs.version }}

      - uses: release-drafter/release-drafter@v5
        id: target_release_notes
        with:
          tag: ${{ steps.semver.outputs.version }}
          name: ${{ steps.semver.outputs.version }}
          version: ${{ steps.semver.outputs.version }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Update Changelog
        uses: stefanzweifel/changelog-updater-action@v1
        with:
          latest-version: ${{ steps.target_release_notes.outputs.tag_name }}
          release-notes: ${{ steps.target_release_notes.outputs.body }}

      - name: Commit updated Changelog
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: 'docs: Update changelog'
          file_pattern: CHANGELOG.md
          branch: main

      - uses: dart-lang/setup-dart@v1
      - uses: subosito/[email protected]
        with:
          flutter-version: '3.7.12'
      - name: Install dependencies
        run: flutter pub get

      - name: Update version
        run: dart run bull pub_version --version=${{ steps.semver.outputs.version }}

      - name: Commit updated pubspec
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: 'chore: Update version for release'
          file_pattern: pubspec.yaml
          branch: main

      - name: Update Git tag
        run: |
          git tag ${{ github.ref_name }} -f
          git push origin ${{ github.ref_name }} -f

      - uses: release-drafter/release-drafter@v5
        with:
          tag: ${{ steps.semver.outputs.version }}
          name: ${{ steps.semver.outputs.version }}
          version: ${{ steps.semver.outputs.version }}
          publish: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Publish
        run: flutter pub publish --force

수정된 내용은 다음과 같이 Bull 패키지를 사용하여 pubspec.yamlversion을 업데이트하는 코드와 수정된 pubspec.yaml 파일을 커밋하는 코드입니다.

...
- name: Update version
  run: dart run bull pub_version --version=$

- name: Commit updated pubspec
  uses: stefanzweifel/git-auto-commit-action@v4
  with:
    commit_message: 'chore: Update version for release'
    file_pattern: pubspec.yaml
    branch: main
...

Bull 패키지의 사용법에 관해서는 다음 링크를 참고하시기 바랍니다.

완료

이것으로 Flutter용으로 개발한 패키지를 GitHub Actions를 사용하여 자동으로 pub.dev에 배포하는 방법에 대해서 알아보았습니다. Flutter용 오픈소스나 공통 패키지를 만들어 배포하고 있다면 여기서 소개한 방법을 사용하여 pub.dev 배포를 자동화해 보시기 바랍니다.

제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!

앱 홍보

책 홍보

스무디 한 잔 마시며 끝내는 React Native 책을 출판한지 벌써 2년이 다되었네요.
이번에도 좋은 기회가 있어서 스무디 한 잔 마시며 끝내는 리액트 + TDD 책을 출판하게 되었습니다.

아래 링크를 통해 제가 쓴 책을 구매하실 수 있습니다.
많은 분들에게 도움이 되면 좋겠네요.

스무디 한 잔 마시며 끝내는 React Native, 비제이퍼블릭
스무디 한 잔 마시며 끝내는 리액트 + TDD, 비제이퍼블릭
[심통]현장에서 바로 써먹는 리액트 with 타입스크립트 : 리액트와 스토리북으로 배우는 컴포넌트 주도 개발, 심통
Posts