GoアプリをGitHubに公開する

この投稿は、GithubでGoアプリケーションを公開する際のチェックリストとその実装です。





TLDR:





  • 基本操作のエントリポイントとしてのMakefile





  • コード品質を改善するためのツールとしてのリンターとテスト





  • アプリケーションを配布する方法としてのDockerfile





  • 新しい変更時にアプリケーションを自動的にビルドしてデプロイする機能としてのGithubアクション





  • リリースとパッケージを公開するためのツールとしてのGoreleaser





その結果、アプリケーションの存在全体を簡単に維持できるようにカスタマイズされたツールを備えた公開アプリケーションが作成されます。実際の例として、pgcenterユーティリティを見ていきます






免責事項:上記のリストは完全に真実ではなく、アプリケーションを公開する過程で私が思いついたものの主観的なリストにすぎません。リストは補足および変更できます。これはすべて1つの大きな私見です。別の見方がある場合、またはいくつかのことがさらに改善できると確信している場合は、コメントでお知らせください。





単純なものから複雑なものに移行します。会議ファイル名の場合、それらはすべて、アプリケーションコードが配置されているプロジェクトのルートを基準にして取得されます。





Makefile

Makefile :

















  • , docker ..









  • , SQL Makefile . Makefile , , . Makefile CI/CD. Makefile :





PROGRAM_NAME = pgcenter

COMMIT=$(shell git rev-parse --short HEAD)
BRANCH=$(shell git rev-parse --abbrev-ref HEAD)
TAG=$(shell git describe --tags |cut -d- -f1)

LDFLAGS = -ldflags "-X main.gitTag=${TAG} -X main.gitCommit=${COMMIT} -X main.gitBranch=${BRANCH}"

.PHONY: help clean dep build install uninstall 

.DEFAULT_GOAL := help

help: ## Display this help screen.
	@echo "Makefile available targets:"
	@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "  * \033[36m%-15s\033[0m %s\n", $$1, $$2}'

dep: ## Download the dependencies.
	go mod download

build: dep ## Build pgcenter executable.
	mkdir -p ./bin
	CGO_ENABLED=0 GOOS=linux GOARCH=${GOARCH} go build ${LDFLAGS} -o bin/${PROGRAM_NAME} ./cmd

clean: ## Clean build directory.
	rm -f ./bin/${PROGRAM_NAME}
	rmdir ./bin
      
      



Makefile.





  • . , Git . , . Git , , . , Git Git . 1 2.





  • help, Makefile - . make make help.





  • Go : , .





, .





. "" , - . , . , . go , golangci-lint gosec. ( ), .





, Makefile





lint: dep ## Lint the source files
	golangci-lint run --timeout 5m -E golint
	gosec -quiet ./...
      
      



golangci-lint , -E . gosec , .





golangci-lint gosec . , .





, .





test: dep ## Run tests
	go test -race -p 1 -timeout 300s -coverprofile=.test_coverage.txt ./... && \
    	go tool cover -func=.test_coverage.txt | tail -n1 | awk '{print "Total test coverage: " $$3}'
	@rm .test_coverage.txt
      
      



, .





Dockerfile

Dockerfile, Docker .





# stage 1: build
FROM golang:1.15 as build
LABEL stage=intermediate
WORKDIR /app
COPY . .
RUN make build

# stage 2: scratch
FROM scratch as scratch
COPY --from=build /app/bin/pgcenter /bin/pgcenter
CMD ["pgcenter"]
      
      



, . , , - .





Docker , Docker Hub. (/).





, Makefile.





docker-build: ## Build docker image
	docker build -t lesovsky/pgcenter:${TAG} .
	docker image prune --force --filter label=stage=intermediate

docker-push: ## Push docker image to registry
	docker push lesovsky/pgcenter:${TAG}
      
      



, TAG Makefile.





Github Actions

(Makefile) (Dockerfile), . Github Actions.





, . , , . , Git Flow, Github Flow, Gitlab Flow .





. master . master release . , master release.





workflow Github Actions. wokflow .





workflow:





  • Default (.github/workflows/default.yml) - flow -, .





  • Release (.github/workflows/release.yml) - flow , Docker .





workflow push pull request master. (job), . Github Actions . .





workflow.





---
name: Release

on:
  push:
    branches: [ release ]

jobs:
  test:
    runs-on: ubuntu-latest
    container: lesovsky/pgcenter-testing:v0.0.1

    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Prepare test environment
        run: prepare-test-environment.sh
      - name: Run lint
        run: make lint
      - name: Run test
        run: make test

  build:
    runs-on: ubuntu-latest
    needs: test
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - name: Build image
        run: make docker-build
      - name: Log in to Docker Hub
        run: docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
      - name: Push image to Docker Hub
        run: make docker-push

  goreleaser:
    runs-on: ubuntu-latest
    needs: [ test, build ]
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - uses: actions/setup-go@v2
        with:
          go-version: 1.15
      - uses: goreleaser/goreleaser-action@v2
        with:
          version: latest
          args: release --rm-dist
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      
      



workflow , push release . workflow . - build goreleaser.





build Docker . , , Secrets, Github .





goreleaser Releases . goreleaser . GITHUB_TOKEN , workflow.





Goreleaser

. Docker . deb rpm . ,

. goreleaser . .goreleaser.yml





before:
  hooks:
  - make dep

builds:
  - binary: pgcenter
    main: ./cmd
    goarch:
      - amd64
    goos:
      - linux
    env:
      - CGO_ENABLED=0
    ldflags:
      - -a -installsuffix cgo
      - -X main.gitTag={{.Tag}} -X main.gitCommit={{.Commit}} -X main.gitBranch={{.Branch}}

archives:
  - builds: [pgcenter]

changelog:
  sort: asc

nfpms:
  - vendor: pgcenter
    homepage: https://github.com/lesovsky/pgcenter
    maintainer: Alexey Lesovsky
    description: Command-line admin tool for observing and troubleshooting Postgres.
    license: BSD-3
    formats: [ deb, rpm ]
      
      



goreleaser Makefile goreleaser . Makefile, .. , .. nfpms .





. , , Actions workflow. , , Actions.





, , , , - Go .





  • gist.github.com





  • golangci-lint





  • gosec





  • Docker multi-stage build





  • GitHub Actions Quick Start





  • Goreleaser:12








All Articles