Skip to content

Commit

Permalink
Draft: build multiple binaries and include them in one package (#160)
Browse files Browse the repository at this point in the history
* feat: leverage go build feature to enable multiple binaries

* chore: add multi-binaries test

* doc: multiple binaries support

* chore: enhance test

* fix: multi test

* fix: syntax

* fix: tag

* fix: build error

* feat: add multi_binaries arg

* test: more usage

* fix: multi_binaries test

* doc: update

* fix: syntax
  • Loading branch information
wangyoucao577 committed Feb 24, 2024
1 parent 588e24a commit e48e16c
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 15 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/autotest.yml
Expand Up @@ -199,3 +199,30 @@ jobs:
overwrite: true
release_tag: v0.1-test-assets
compress_assets: ${{ matrix.compress_assets }}

multi-binaries-test:
name: Multi Binaries Test
runs-on: ubuntu-latest
strategy:
matrix:
goos: [linux, windows, darwin]
goarch: [amd64]
project_path: [./test/multi-binaries/..., './test/multi-binaries/cmd1 ./test/multi-binaries/cmd2']
steps:
- name: Set BUILD_TIME env
run: echo BUILD_TIME=$(date -u +%Y%m%dT%H%M%S) >> ${GITHUB_ENV}
- name: Checkout
uses: actions/checkout@v4
- name: Run go-release-action on test code
uses: ./
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
goarch: ${{ matrix.goarch }}
project_path: ${{ matrix.project_path }}
pre_command: go mod init localtest
extra_files: LICENSE README.md
build_flags: -v -tags v0.1-test-assets-${{ env.BUILD_TIME }}
overwrite: true
release_tag: v0.1-test-assets
multi_binaries: true
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -23,6 +23,7 @@ Automatically publish `Go` binaries to Github Release Assets through Github Acti
- Support private repositories.
- Support executable compression by [upx](https://github.com/upx/upx).
- Support retry if upload phase fails.
- Support build multiple binaries and include them in one package(`.zip/.tar.gz`).

## Usage

Expand Down Expand Up @@ -62,7 +63,7 @@ jobs:
| goamd64 | **Optional** | `GOAMD64` is the running programs amd64 microarchitecture level, which is available since `go1.18`. It should only be used when `GOARCH` is `amd64`: one of `v1`, `v2`, `v3`, `v4`. |
| goarm | **Optional** | `GOARM` is the running programs arm microarchitecture level, which is available since `go1.1`. It should only be used when `GOARCH` is `arm`: one of `5`, `6`, `7`, |
| goversion | **Optional** | The `Go` compiler version. `latest`([check it here](https://go.dev/VERSION?m=text)) by default, optional `1.13`, `1.14`, `1.15`, `1.16`, `1.17`, `1.18`, `1.19`. You can also define a specific minor release, such as `1.19.5`. <br>Alternatively takes a download URL or a path to go.mod instead of version string. Make sure your URL references the `linux-amd64` package. You can find the URL on [Go - Downloads](https://go.dev/dl/).<br>e.g., `https://dl.google.com/go/go1.13.1.linux-amd64.tar.gz`. |
| project_path | **Optional** | Where to run `go build`. <br>Use `.` by default. |
| project_path | **Optional** | Where to run `go build`. <br>Use `.` by default. <br>If enable `multi_binaries: true`, you can use `project_path: ./cmd/...` or `project_path: ./cmd/app1 ./cmd/app2` to build multiple binaries and include them in one package. |
| binary_name | **Optional** | Specify another binary name if do not want to use repository basename. <br>Use your repository's basename if not set. |
| pre_command | **Optional** | Extra command that will be executed before `go build`. You may want to use it to solve dependency if you're NOT using [Go Modules](https://github.com/golang/go/wiki/Modules). |
| build_command | **Optional** | The actual command to build binary, typically `go build`. You may want to use other command wrapper, e.g., [packr2](https://github.com/gobuffalo/packr/tree/master/v2), example `build_command: 'packr2 build'`. Remember to use `pre_command` to set up `packr2` command in this scenario.<br>It also supports the `make`(`Makefile`) building system, example `build_command: make`. In this case both `build_flags` and `ldflags` will be ignored since they should be written in your `Makefile` already. Also, please make sure the generated binary placed in the path where `make` runs, i.e., `project_path`. |
Expand Down
6 changes: 6 additions & 0 deletions action.yml
Expand Up @@ -103,6 +103,10 @@ inputs:
description: 'Upload release assets or not'
required: false
default: 'TRUE'
multi_binaries:
description: 'Build and package multiple binaries together'
required: false
default: 'FALSE'

outputs:
release_asset_dir:
Expand Down Expand Up @@ -136,6 +140,8 @@ runs:
- ${{ inputs.retry }}
- ${{ inputs.post_command }}
- ${{ inputs.compress_assets }}
- ${{ inputs.upload }}
- ${{ inputs.multi_binaries }}

branding:
icon: 'package'
Expand Down
36 changes: 24 additions & 12 deletions release.sh
Expand Up @@ -95,20 +95,30 @@ else
fi
fi


# build
BUILD_ARTIFACTS_FOLDER=build-artifacts-$(date +%s)
RELEASE_ASSET_DIR=${INPUT_PROJECT_PATH}/${BUILD_ARTIFACTS_FOLDER}
mkdir -p ${RELEASE_ASSET_DIR}
cd ${INPUT_PROJECT_PATH}
if [[ "${INPUT_BUILD_COMMAND}" =~ ^make.* ]]; then
# start with make, assumes using make to build golang binaries, execute it directly
GOAMD64=${GOAMD64_FLAG} GOARM=${GOARM_FLAG} GOOS=${INPUT_GOOS} GOARCH=${INPUT_GOARCH} eval ${INPUT_BUILD_COMMAND}
if [ -f "${BINARY_NAME}${EXT}" ]; then
# assumes the binary will be generated in current dir, copy it for later processes
cp ${BINARY_NAME}${EXT} ${BUILD_ARTIFACTS_FOLDER}/
fi
if [ ${INPUT_MULTI_BINARIES^^} == 'TRUE' ]; then
RELEASE_ASSET_DIR=${BUILD_ARTIFACTS_FOLDER}
mkdir -p ${RELEASE_ASSET_DIR}

# leverage golang feature to support multiple binaries
# for example, 'go build -o xxx ./cmd/...' or 'go build -o xxx ./cmd/app1 ./cmd/app2' to generate multiple binaries'
GOAMD64=${GOAMD64_FLAG} GOARM=${GOARM_FLAG} GOOS=${INPUT_GOOS} GOARCH=${INPUT_GOARCH} ${INPUT_BUILD_COMMAND} ${INPUT_BUILD_FLAGS} -o ${BUILD_ARTIFACTS_FOLDER} ${INPUT_PROJECT_PATH}
else
GOAMD64=${GOAMD64_FLAG} GOARM=${GOARM_FLAG} GOOS=${INPUT_GOOS} GOARCH=${INPUT_GOARCH} ${INPUT_BUILD_COMMAND} -o ${BUILD_ARTIFACTS_FOLDER}/${BINARY_NAME}${EXT} ${INPUT_BUILD_FLAGS} ${LDFLAGS_PREFIX} "${INPUT_LDFLAGS}"
RELEASE_ASSET_DIR=${INPUT_PROJECT_PATH}/${BUILD_ARTIFACTS_FOLDER}
mkdir -p ${RELEASE_ASSET_DIR}
cd ${INPUT_PROJECT_PATH}
if [[ "${INPUT_BUILD_COMMAND}" =~ ^make.* ]]; then
# start with make, assumes using make to build golang binaries, execute it directly
GOAMD64=${GOAMD64_FLAG} GOARM=${GOARM_FLAG} GOOS=${INPUT_GOOS} GOARCH=${INPUT_GOARCH} eval ${INPUT_BUILD_COMMAND}
if [ -f "${BINARY_NAME}${EXT}" ]; then
# assumes the binary will be generated in current dir, copy it for later processes
cp ${BINARY_NAME}${EXT} ${BUILD_ARTIFACTS_FOLDER}/
fi
else
GOAMD64=${GOAMD64_FLAG} GOARM=${GOARM_FLAG} GOOS=${INPUT_GOOS} GOARCH=${INPUT_GOARCH} ${INPUT_BUILD_COMMAND} -o ${BUILD_ARTIFACTS_FOLDER}/${BINARY_NAME}${EXT} ${INPUT_BUILD_FLAGS} ${LDFLAGS_PREFIX} "${INPUT_LDFLAGS}"
fi
fi

# executable compression
Expand All @@ -126,7 +136,9 @@ fi
if [ ! -z "${INPUT_EXTRA_FILES}" ]; then
cd ${GITHUB_WORKSPACE}
cp -r ${INPUT_EXTRA_FILES} ${RELEASE_ASSET_DIR}/
cd ${INPUT_PROJECT_PATH}
if [ ! ${INPUT_MULTI_BINARIES^^} == 'TRUE' ]; then
cd ${INPUT_PROJECT_PATH}
fi
fi

cd ${BUILD_ARTIFACTS_FOLDER}
Expand Down
2 changes: 2 additions & 0 deletions test/.gitignore
@@ -1,3 +1,5 @@
go.mod
go.sum
testmain
cmd1
cmd2
26 changes: 26 additions & 0 deletions test/multi-binaries/cmd1/test_main.go
@@ -0,0 +1,26 @@
package main

import (
"fmt"
"os"
)

const notSet string = "not set"

// these information will be collected when build, by `-ldflags "-X main.gitCommit=06b8d24"`
var (
buildTime = notSet
gitCommit = notSet
gitRef = notSet
)

func printVersion() {
fmt.Printf("Build Time: %s\n", buildTime)
fmt.Printf("Git Commit: %s\n", gitCommit)
fmt.Printf("Git Ref: %s\n", gitRef)
}

func main() {
fmt.Printf("%s Hello Action!\n", os.Args[0])
printVersion()
}
26 changes: 26 additions & 0 deletions test/multi-binaries/cmd2/test_main.go
@@ -0,0 +1,26 @@
package main

import (
"fmt"
"os"
)

const notSet string = "not set"

// these information will be collected when build, by `-ldflags "-X main.gitCommit=06b8d24"`
var (
buildTime = notSet
gitCommit = notSet
gitRef = notSet
)

func printVersion() {
fmt.Printf("Build Time: %s\n", buildTime)
fmt.Printf("Git Commit: %s\n", gitCommit)
fmt.Printf("Git Ref: %s\n", gitRef)
}

func main() {
fmt.Printf("%s Hello Action!\n", os.Args[0])
printVersion()
}
7 changes: 5 additions & 2 deletions test/test_main.go
@@ -1,6 +1,9 @@
package main

import "fmt"
import (
"fmt"
"os"
)

const notSet string = "not set"

Expand All @@ -18,6 +21,6 @@ func printVersion() {
}

func main() {
fmt.Println("Hello Action!")
fmt.Printf("%s Hello Action!\n", os.Args[0])
printVersion()
}

0 comments on commit e48e16c

Please sign in to comment.