Skip to main content

내부적으로 배포 및 공유하기

소프트웨어를 만들다보면 코드를 공개적으로 오픈할 때도 있지만 내부적으로만 공개를 해야할 필요가 있을 때도 있습니다. 저는 주로 go 언어를 사용하여 개발을 하고 소프트웨어를 만들다보니 goreleaser를 사용해서 배포를 합니다.

하지만 소스코드가 공개된 저장소로부터 릴리즈된 소프트웨어는 homebrew 패키지를 통해서 접근이 가능하지만 소스코드가 공개되지 않은 저장소로부터 릴리즈된 소프트웨어는 homebrew를 통해서 접근할 수 없습니다. 즉, 비공개 저장소로 접근을 하기 위해서는 기존 homebrew의 동작을 이해하고 최신 릴리즈된 소프트웨어를 다운로드 받을 수 있도록 기능을 간소화해야 했습니다.

먼저, 깃헙의 비공개 저장소로 접근할 수 있도록 토큰을 발급받습니다.

토큰 발급 받기

  • Settings > Developer settings > Personal access tokens

계정 내의 여러 저장소가 있을 경우 모든 저장소에 접근이 가능한 토큰을 발급받지 말고 조직 내 구성원들에게 배포하려는 소프트웨어가 릴리즈된 비공개 저장소로만 접근이 허용된 토큰을 발급받아야 합니다.

brew tap 동작에 따른 내부 변화 살펴보기

  • 제 깃헙 계정은 ghdwlsgur이며 저장소명은 oops입니다.
brew tap ghdwlsgur/oops

위 명령어와 같이 brew tap 명령어를 실행할 경우 특정 파일이 생성됩니다.

  • /opt/homebrew/Library/Taps/ghdwlsgur/homebrew-oops/oops.rb
  • /opt/homebrew/Library/Taps/{{Owner}}/homebrew-{{Repository}}/{{File}}

brew install 동작에 따른 내부 변화 살펴보기

1. 아래 경로에 파일 생성

  • 압축 릴리즈 파일을 다운로드 받으면 README.mdLICENSE가 존재
  • bin 폴더 아래 바이너리 파일 존재
📦 /opt/homebrew/Cellar/oops/0.0.17/
├── 📄 README.md # 리드미 파일
├── 📄 LICENSE # 라이센스
└── 📁 bin
└── 📄 oops # 바이너리

2. 심볼릭 링크 설정

  • /opt/homebrew/bin/oops (lrwxr-xr-x) -> /opt/homebrew/Cellar/oops/0.0.17/bin/oops (r-xr-xr-x)
  • 위 경로가 다른 두 바이너리 파일 간 심볼릭 링크 설정
# 어느 경로에서든지 커맨더 실행
ln -sf ../Cellar/oops/0.0.17/bin/oops /opt/homebrew/bin/oops
📦 /opt/homebrew/Cellar/{{REPO명}}/{{릴리즈버전}}/
├── 📄 README.md # rw-r--r--
├── 📄 LICENSE # rw-r--r--
└── 📁 bin # drwxr-xr-x
└── 📄 oops <-> 📄 /opt/homebrew/bin/{{REPO명}} # 바이너리 링크

3. 설치 확인

  • brew list로 설치 확인 시에 아래와 같은 바이너리 파일 경로 반환
brew list
/opt/homebrew/Cellar/oops/0.0.17/bin/oops

brew uninstall 내부 변화 살펴보기

  • brew uninstall oops 실행시 아래 두 파일 삭제
- 📄 /opt/homebrew/Cellar/oops 삭제
- 📄 /opt/homebrew/bin/oops 삭제

위와 같이 brew의 tap과 install의 전반적인 동작을 살펴보고 이러한 동작을 github api를 사용하여 비공개 저장소로 접근 및 최신 릴리즈 다운로드 기능을 가진 privrew를 만들게 되었습니다.

즉, 깃헙 api를 사용하여 최신 릴리즈 버전의 바이너리 파일 url 경로를 가져오고 해당 url 경로로 다운로드 요청을 하여 정해진 경로에 바이너리 파일을 저장한 뒤에 심볼릭 링크를 설정해주면 brew 패키지 매니저에서의 install 동작과 동일하게 동작하게 됩니다. 이 기능을 코드로 구현한 것이 privrew의 주요 기능이 되겠습니다.

release 최신 버전 스펙 조회

curl -sL -H "Authorization: token {{.Env.GITHUB_TOKEN}}" \
https://api.github.com/repos/{{.ProjectOwner}}/{{.ProjectName}}/releases/latest |
jq '.assets[] | select(.name == "{{.ReleaseFile}}") | .url' |
tr -d '"'
# example
curl -sL \
-H "Authorization: token github_pat_1234" \
https://api.github.com/repos/ghdwlsgur/oops/releases/latest | jq '.assets[]'

release 파일 다운로드

curl -L -H 'Accept: application/octet-stream' -H "Authorization: token [TOKEN]" \ [URL] --output "[OUTPUT]"

# example
curl -L -H 'Accept: application/octet-stream' -H "Authorization: token github_pat_1234" \ https://github.com/ghdwlsgur/oops/releases/download/v0.0.2/oops_0.0.2_Darwin_arm64.tar.gz --output "oops"
caution

릴리즈 파일을 다운로드 받을 때 요청 Accept 헤더에 application/octet-stream을 추가해야만 바이너리 파일을 다운로드 받을 수 있으며 추가하지 않을 경우 바이너리 파일이 아닌 파일의 스펙만 명시된 소스코드 파일만 다운로드 받게 되므로 바이너리 파일을 다운로드 받기 위해서는 위 헤더를 필수로 추가해주어야만 합니다.

그 밖에도 루비 파일을 사용해서 download 받기 위해서는 아래 GITHUB API를 참고하실 수 있습니다.

curl -H 'Authorization: token [TOKEN]' \
-H 'Accept: application/vnd.github.v3.raw' \
-O \
-L [ROBY REPO URL]

# example
curl -H 'Authorization: token github_pat_1234' \
-H 'Accept: application/vnd.github.v3.raw' \
-O \
-L https://api.github.com/repos/ghdwlsgur/homebrew-oops/contents/oops.rb

이러한 기능으로 비공개 저장소에 배포된 릴리즈 파일을 저장소에 접근할 수 있는 토큰만 가지고 있다면 내부적으로 쉽게 배포 및 다운로드를 가능하게 할 수 있으며 아래는 privrew 설치법과 사용법입니다.

먼저, privrew를 설치합니다.

brew tap ghdwlsgur/privrew
brew install privrew

privrew install

다운 받으려는 바이너리 파일의 저장소명과 유저이름, 저장소에 접근할 수 있는 토큰을 입력하여 다운로드 받습니다.

privrew install [USERNAME]/[REPO] -t [TOKEN]

brew list

정식 패키지매니저인 homebrew의 list 기능으로 위에서 다운받은 소프트웨어의 설치를 확인합니다.

brew list [REPO] # 또는 릴리즈명

코드는 github에서 확인하실 수 있습니다.