diff --git a/.forgejo/actions/build-release/action.yml b/.forgejo/actions/build-release/action.yml new file mode 100644 index 0000000000..01fdfdedfc --- /dev/null +++ b/.forgejo/actions/build-release/action.yml @@ -0,0 +1,154 @@ +name: 'Build release' +author: 'Forgejo authors' +description: | + Build release + +inputs: + forgejo: + description: 'URL of the Forgejo instance where the release is uploaded' + required: true + owner: + description: 'User or organization where the release is uploaded, relative to the Forgejo instance' + required: true + repository: + description: 'Repository where the release is uploaded, relative to the owner' + required: true + doer: + description: 'Name of the user authoring the release' + required: true + tag-version: + description: 'Version of the release derived from the tag withint the leading v' + required: true + suffix: + description: 'Suffix to add to the image tag' + token: + description: 'token' + required: true + dockerfile: + description: 'path to the dockerfile' + default: 'Dockerfile' + platforms: + description: 'Coma separated list of platforms' + default: 'linux/amd64,linux/arm64' + release-notes: + description: 'Full text of the release notes' + default: 'Release notes placeholder' + binary-name: + description: 'Name of the binary' + binary-path: + description: 'Path of the binary within the container to extract into binary-name' + verbose: + description: 'Increase the verbosity level' + default: 'false' + +runs: + using: "composite" + steps: + - run: echo "${{ github.action_path }}" >> $GITHUB_PATH + shell: bash + + - name: Install dependencies + run: | + apt-get install -y -qq xz-utils + + - name: set -x if verbose is required + id: verbose + run: | + if ${{ inputs.verbose }} ; then + echo "shell=set -x" >> "$GITHUB_OUTPUT" + fi + + - name: Create the insecure and buildx-config variables for the container registry + id: registry + run: | + ${{ steps.verbose.outputs.shell }} + url="${{ inputs.forgejo }}" + hostport=${url##http*://} + hostport=${hostport%%/} + echo "host-port=${hostport}" >> "$GITHUB_OUTPUT" + if ! [[ $url =~ ^http:// ]] ; then + exit 0 + fi + cat >> "$GITHUB_OUTPUT" < /etc/docker/daemon.json < ~/.docker/config.json + env: + CI_REGISTRY: "${{ steps.registry.outputs.host-port }}" + + - name: Build the container image for each architecture + uses: https://github.com/docker/build-push-action@v4 + # workaround until https://github.com/docker/build-push-action/commit/d8823bfaed2a82c6f5d4799a2f8e86173c461aba is in @v4 or @v5 is released + env: + ACTIONS_RUNTIME_TOKEN: '' + with: + context: . + push: true + file: ${{ inputs.dockerfile }} + platforms: ${{ inputs.platforms }} + tags: ${{ steps.registry.outputs.host-port }}/${{ inputs.owner }}/${{ inputs.repository }}:${{ inputs.tag-version }}${{ inputs.suffix }} + + - name: Extract the binary from the container images into the release directory + if: inputs.binary-name != '' + run: | + ${{ steps.verbose.outputs.shell }} + mkdir -p release + cd release + for platform in $(echo ${{ inputs.platforms }} | tr ',' ' '); do + arch=$(echo $platform | sed -e 's|linux/||g' -e 's|arm/v6|arm-6|g') + docker create --platform $platform --name forgejo-$arch ${{ steps.registry.outputs.host-port }}/${{ inputs.owner }}/${{ inputs.repository }}:${{ inputs.tag-version }}${{ inputs.suffix }} + binary="${{ inputs.binary-name }}-${{ inputs.tag-version }}-linux" + docker cp forgejo-$arch:${{ inputs.binary-path }} $binary-$arch + chmod +x $binary-$arch + # the displayed version has a + instead of the first -, deal with it + pattern=$(echo "${{ inputs.tag-version }}" | tr - .) + if ! ./$binary-$arch --version | grep "$pattern" ; then + echo "ERROR: expected version pattern $pattern not found in the output of $binary-$arch --version" + ./$binary-$arch --version + exit 1 + fi + xz --keep -9 $binary-$arch + shasum -a 256 $binary-$arch > $binary-$arch.sha256 + shasum -a 256 $binary-$arch.xz > $binary-$arch.xz.sha256 + docker rm forgejo-$arch + done + + - name: publish release + if: inputs.binary-name != '' + uses: https://code.forgejo.org/actions/forgejo-release@v1 + with: + direction: upload + release-dir: release + release-notes: "${{ inputs.release-notes }}" + token: ${{ inputs.token }} + verbose: ${{ steps.verbose.outputs.value }} diff --git a/.forgejo/actions/publish-release/action.yml b/.forgejo/actions/publish-release/action.yml new file mode 100644 index 0000000000..569ec55bfd --- /dev/null +++ b/.forgejo/actions/publish-release/action.yml @@ -0,0 +1,110 @@ +name: 'Publish release' +author: 'Forgejo authors' +description: | + Publish release + +inputs: + forgejo: + description: 'URL of the Forgejo instance where the release is uploaded (e.g. https://codeberg.org)' + required: true + from-owner: + description: 'the owner from which a release is to be copied (e.g forgejo-integration)' + required: true + to-owner: + description: 'the owner to which a release is to be copied (e.g. forgejo-experimental). It has be an organization in which doer has the required permissions. Or be the same as the doer' + required: true + repo: + description: 'the repository from which a release is to be copied relative to from-owner and to-owner' + default: 'forgejo' + ref-name: + description: 'ref_name of the tag of the release to be copied (e.g. github.ref_name)' + required: true + doer: + description: 'Name of the user authoring the release (e.g. release-team). The user must be authorized to create packages in to-owner and releases in to-owner/repo' + required: true + token: + description: 'application token created on forgejo by the doer, with a scope allowing it to create packages in to-owner and releases in to-owner/repo' + required: true + gpg-private-key: + description: 'GPG Private Key to sign the release artifacts' + gpg-passphrase: + description: 'Passphrase of the GPG Private Key' + verbose: + description: 'Increase the verbosity level' + default: 'false' + +runs: + using: "composite" + steps: + - id: hostport + run: | + url="${{ inputs.forgejo }}" + hostport=${url##http*://} + hostport=${hostport%%/} + echo "value=$hostport" >> "$GITHUB_OUTPUT" + + - id: tag-version + run: | + version="${{ inputs.ref-name }}" + version=${version##*v} + echo "value=$version" >> "$GITHUB_OUTPUT" + + - name: Create the release notes + id: release-notes + run: | + anchor=${{ steps.tag-version.outputs.value }} + anchor=${anchor//./-} + cat >> "$GITHUB_OUTPUT" < /app/gitea/gitea ; chmod +x /app/gitea/gitea diff --git a/.forgejo/testdata/build-release/Makefile b/.forgejo/testdata/build-release/Makefile new file mode 100644 index 0000000000..406acd06d2 --- /dev/null +++ b/.forgejo/testdata/build-release/Makefile @@ -0,0 +1,5 @@ +VERSION ?= $(shell cat VERSION 2>/dev/null) +sources-tarbal: + mkdir -p dist/release + echo $(VERSION) > VERSION + sources=forgejo-src-$(VERSION).tar.gz ; tar --transform 's|^./|forgejo-src-$(VERSION)/|' -czf dist/release/forgejo-src-$(VERSION).tar.gz . ; cd dist/release ; shasum -a 256 $$sources > $$sources.sha256 diff --git a/.forgejo/testdata/build-release/modules/public/bindata.go b/.forgejo/testdata/build-release/modules/public/bindata.go new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.forgejo/testdata/build-release/public/assets/css/placeholder b/.forgejo/testdata/build-release/public/assets/css/placeholder new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.forgejo/testdata/build-release/public/assets/fonts/placeholder b/.forgejo/testdata/build-release/public/assets/fonts/placeholder new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.forgejo/testdata/build-release/public/assets/js/placeholder b/.forgejo/testdata/build-release/public/assets/js/placeholder new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.forgejo/workflows/build-release-integration.yml b/.forgejo/workflows/build-release-integration.yml new file mode 100644 index 0000000000..d893bd39af --- /dev/null +++ b/.forgejo/workflows/build-release-integration.yml @@ -0,0 +1,99 @@ +name: Integration tests for the release process + +on: + push: + paths: + - Makefile + - Dockerfile + - Dockerfile.rootless + - docker/** + - .forgejo/actions/build-release/action.yml + - .forgejo/workflows/build-release.yml + - .forgejo/workflows/build-release-integration.yml + +jobs: + release-simulation: + runs-on: self-hosted + if: secrets.ROLE != 'forgejo-integration' && secrets.ROLE != 'forgejo-experimental' && secrets.ROLE != 'forgejo-release' + steps: + - uses: actions/checkout@v3 + + - id: forgejo + uses: https://code.forgejo.org/actions/setup-forgejo@v1 + with: + user: root + password: admin1234 + image-version: 1.19 + lxc-ip-prefix: 10.0.9 + + - name: publish the forgejo release + run: | + set -x + + version=1.2.3 + cat > /etc/docker/daemon.json < $binary$suffix + if test "$suffix" = .xz ; then + unxz --keep $binary$suffix + fi + chmod +x $binary + ./$binary --version | grep $version + curl --fail -L -sS $url/root/forgejo/releases/download/v$version/$binary$suffix.sha256 > $binary$suffix.sha256 + shasum -a 256 --check $binary$suffix.sha256 + rm $binary$suffix + done + done + + sources=forgejo-src-$version.tar.gz + curl --fail -L -sS $url/root/forgejo/releases/download/v$version/$sources > $sources + curl --fail -L -sS $url/root/forgejo/releases/download/v$version/$sources.sha256 > $sources.sha256 + shasum -a 256 --check $sources.sha256 + + docker pull ${{ steps.forgejo.outputs.host-port }}/root/forgejo:$version + docker pull ${{ steps.forgejo.outputs.host-port }}/root/forgejo:$version-rootless diff --git a/.forgejo/workflows/build-release.yml b/.forgejo/workflows/build-release.yml new file mode 100644 index 0000000000..7e6aabb8a3 --- /dev/null +++ b/.forgejo/workflows/build-release.yml @@ -0,0 +1,186 @@ +name: Build release + +on: + push: + tags: 'v*' + +jobs: + release: + runs-on: self-hosted + # root is used for testing, allow it + if: secrets.ROLE == 'forgejo-integration' || github.repository_owner == 'root' + steps: + - uses: actions/checkout@v3 + + - name: Increase the verbosity when there are no secrets + id: verbose + run: | + if test -z "${{ secrets.TOKEN }}"; then + value=true + else + value=false + fi + echo "value=$value" >> "$GITHUB_OUTPUT" + + - name: Sanitize the name of the repository + id: repository + run: | + set -x # comment out + repository="${{ github.repository }}" + echo "value=${repository##*/}" >> "$GITHUB_OUTPUT" + + - name: When in a test environment, create a token + id: token + if: ${{ secrets.TOKEN == '' }} + run: | + apt-get -qq install -y jq + url="${{ env.GITHUB_SERVER_URL }}" + hostport=${url##http*://} + hostport=${hostport%%/} + doer=root + api=http://$doer:admin1234@$hostport/api/v1/users/$doer/tokens + curl -sS -X DELETE $api/release + token=$(curl -sS -X POST -H 'Content-Type: application/json' --data-raw '{"name": "release", "scopes": ["all"]}' $api | jq --raw-output .sha1) + echo "value=${token}" >> "$GITHUB_OUTPUT" + + - uses: https://code.forgejo.org/actions/setup-go@v4 + with: + go-version: ">=1.20" + check-latest: true + + - name: Create the version from ref_name + id: tag-version + run: | + version="${{ github.ref_name }}" + version=${version##*v} + echo "value=$version" >> "$GITHUB_OUTPUT" + + - name: Create the release notes + id: release-notes + run: | + cat >> "$GITHUB_OUTPUT" < 2.0.1 + # css-loader: 6.8.1 => 6.8.1 + # esbuild-loader: 3.0.1 => 3.0.1 + # license-checker-webpack-plugin: 0.2.1 => 0.2.1 + # monaco-editor-webpack-plugin: 7.0.1 => 7.0.1 + # vue-loader: 17.2.2 => 17.2.2 + # webpack: 5.87.0 => 5.87.0 + # webpack-cli: 5.1.4 => 5.1.4 + # + chown -R $(id -u) . + make VERSION=$version TAGS=bindata sources-tarbal + mv dist/release release + + ( + tmp=$(mktemp -d) + tar --directory $tmp -zxvf release/*$version*.tar.gz + cd $tmp/* + # + # Verify `make frontend` files are available + # + test -d public/assets/css + test -d public/assets/fonts + test -d public/assets/js + # + # Verify `make generate` files are available + # + test -f modules/public/bindata.go + # + # Sanity check to verify that the source tarbal knows the + # version and is able to rebuild itself from it. + # + # When in sources the version is determined with git. + # When in the tarbal the version is determined from a VERSION file. + # + make sources-tarbal + tarbal=$(echo dist/release/*$version*.tar.gz) + if ! test -f $tarbal ; then + echo $tarbal does not exist + find dist release + exit 1 + fi + ) + + - name: build container & release (when TOKEN secret is not set) + if: ${{ secrets.TOKEN == '' }} + uses: ./.forgejo/actions/build-release + with: + forgejo: "${{ env.GITHUB_SERVER_URL }}" + owner: "${{ env.GITHUB_REPOSITORY_OWNER }}" + repository: "${{ steps.repository.outputs.value }}" + doer: root + tag-version: "${{ steps.tag-version.outputs.value }}" + token: ${{ steps.token.outputs.value }} + platforms: linux/amd64,linux/arm64,linux/arm/v6 + release-notes: "${{ steps.release-notes.outputs.value }}" + binary-name: forgejo + binary-path: /app/gitea/gitea + verbose: ${{ steps.verbose.outputs.value }} + + - name: build rootless container (when TOKEN secret is not set) + if: ${{ secrets.TOKEN == '' }} + uses: ./.forgejo/actions/build-release + with: + forgejo: "${{ env.GITHUB_SERVER_URL }}" + owner: "${{ env.GITHUB_REPOSITORY_OWNER }}" + repository: "${{ steps.repository.outputs.value }}" + doer: root + tag-version: "${{ steps.tag-version.outputs.value }}" + token: ${{ steps.token.outputs.value }} + platforms: linux/amd64,linux/arm64,linux/arm/v6 + suffix: -rootless + dockerfile: Dockerfile.rootless + verbose: ${{ steps.verbose.outputs.value }} + + - name: build container & release (when TOKEN secret is set) + if: ${{ secrets.TOKEN != '' }} + uses: ./.forgejo/actions/build-release + with: + forgejo: "${{ env.GITHUB_SERVER_URL }}" + owner: "${{ env.GITHUB_REPOSITORY_OWNER }}" + repository: "${{ steps.repository.outputs.value }}" + doer: "${{ secrets.DOER }}" + tag-version: "${{ steps.tag-version.outputs.value }}" + token: "${{ secrets.TOKEN }}" + platforms: linux/amd64,linux/arm64,linux/arm/v6 + release-notes: "${{ steps.release-notes.outputs.value }}" + binary-name: forgejo + binary-path: /app/gitea/gitea + verbose: ${{ steps.verbose.outputs.value }} + + - name: build rootless container (when TOKEN secret is set) + if: ${{ secrets.TOKEN != '' }} + uses: ./.forgejo/actions/build-release + with: + forgejo: "${{ env.GITHUB_SERVER_URL }}" + owner: "${{ env.GITHUB_REPOSITORY_OWNER }}" + repository: "${{ steps.repository.outputs.value }}" + doer: "${{ secrets.DOER }}" + tag-version: "${{ steps.tag-version.outputs.value }}" + token: "${{ secrets.TOKEN }}" + platforms: linux/amd64,linux/arm64,linux/arm/v6 + suffix: -rootless + dockerfile: Dockerfile.rootless + verbose: ${{ steps.verbose.outputs.value }} diff --git a/.forgejo/workflows/publish-release.yml b/.forgejo/workflows/publish-release.yml new file mode 100644 index 0000000000..c76e78cc12 --- /dev/null +++ b/.forgejo/workflows/publish-release.yml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: MIT +# +# See also https://forgejo.org/docs/next/developer/RELEASE/#release-process +# +# https://codeberg.org/forgejo-experimental/forgejo +# +# Copies a release from codeberg.org/forgejo-integration to codeberg.org/forgejo-experimental +# +# ROLE: forgejo-experimental +# FORGEJO: https://codeberg.org +# FROM_OWNER: forgejo-integration +# TO_OWNER: forgejo-experimental +# DOER: forgejo-experimental-ci +# TOKEN: +# +# https://forgejo.octopuce.forgejo.org/forgejo/forgejo +# +# Copies & sign a release from codeberg.org/forgejo-integration to codeberg.org/forgejo +# +# ROLE: forgejo-release +# FORGEJO: https://codeberg.org +# FROM_OWNER: forgejo-integration +# TO_OWNER: forgejo +# DOER: release-team +# TOKEN: +# GPG_PRIVATE_KEY: +# GPG_PASSPHRASE: +# +name: Pubish release + +on: + push: + tags: 'v*' + +jobs: + publish: + runs-on: self-hosted + if: secrets.DOER != '' && secrets.FORGEJO != '' && secrets.TO_OWNER != '' && secrets.FROM_OWNER != '' && secrets.TOKEN != '' + steps: + - name: install the certificate authority + if: secrets.ROLE == 'forgejo-release' + run: | + apt-get install -qq -y wget + wget --no-check-certificate -O /usr/local/share/ca-certificates/enough.crt https://forgejo.octopuce.forgejo.org/forgejo/enough/raw/branch/main/certs/2023-05-13/ca.crt + update-ca-certificates --fresh + + - uses: actions/checkout@v3 + + - name: copy & sign binaries and container images from one owner to another + uses: ./.forgejo/actions/publish-release + with: + forgejo: ${{ secrets.FORGEJO }} + from-owner: ${{ secrets.FROM_OWNER }} + to-owner: ${{ secrets.TO_OWNER }} + ref-name: ${{ github.ref_name }} + doer: ${{ secrets.DOER }} + token: ${{ secrets.TOKEN }} + gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} + gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }} + verbose: ${{ secrets.VERBOSE }} diff --git a/Dockerfile b/Dockerfile index 730413ebb8..470ded4da1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,6 @@ -#Build stage -FROM docker.io/library/golang:1.20-alpine3.18 AS build-env +FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx + +FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.20-alpine3.18 as build-env ARG GOPROXY ENV GOPROXY ${GOPROXY:-direct} @@ -9,19 +10,33 @@ ARG TAGS="sqlite sqlite_unlock_notify" ENV TAGS "bindata timetzdata $TAGS" ARG CGO_EXTRA_CFLAGS -#Build deps +# +# Transparently cross compile for the target platform +# +COPY --from=xx / / +ARG TARGETPLATFORM +RUN apk --no-cache add clang lld +RUN xx-apk --no-cache add gcc musl-dev +ENV CGO_ENABLED=1 +RUN xx-go --wrap +# +# for go generate and binfmt to find +# without it the generate phase will fail with +# #19 25.04 modules/public/public_bindata.go:8: running "go": exit status 1 +# #19 25.39 aarch64-binfmt-P: Could not open '/lib/ld-musl-aarch64.so.1': No such file or directory +# why exactly is it needed? where is binfmt involved? +# +RUN cp /*-alpine-linux-musl*/lib/ld-musl-*.so.1 /lib || true + RUN apk --no-cache add build-base git nodejs npm -#Setup repo COPY . ${GOPATH}/src/code.gitea.io/gitea WORKDIR ${GOPATH}/src/code.gitea.io/gitea -#Checkout version if set -RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \ - && make clean-all build - -# Begin env-to-ini build -RUN go build contrib/environment-to-ini/environment-to-ini.go +RUN make clean-all +RUN make frontend +RUN go build contrib/environment-to-ini/environment-to-ini.go && xx-verify environment-to-ini +RUN make go-check generate-backend static-executable && xx-verify gitea FROM docker.io/library/alpine:3.18 LABEL maintainer="contact@forgejo.org" diff --git a/Dockerfile.rootless b/Dockerfile.rootless index 39c13fbb6d..78ee81b4f4 100644 --- a/Dockerfile.rootless +++ b/Dockerfile.rootless @@ -1,5 +1,6 @@ -#Build stage -FROM docker.io/library/golang:1.20-alpine3.18 AS build-env +FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx + +FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.20-alpine3.18 as build-env ARG GOPROXY ENV GOPROXY ${GOPROXY:-direct} @@ -9,19 +10,33 @@ ARG TAGS="sqlite sqlite_unlock_notify" ENV TAGS "bindata timetzdata $TAGS" ARG CGO_EXTRA_CFLAGS -#Build deps +# +# Transparently cross compile for the target platform +# +COPY --from=xx / / +ARG TARGETPLATFORM +RUN apk --no-cache add clang lld +RUN xx-apk --no-cache add gcc musl-dev +ENV CGO_ENABLED=1 +RUN xx-go --wrap +# +# for go generate and binfmt to find +# without it the generate phase will fail with +# #19 25.04 modules/public/public_bindata.go:8: running "go": exit status 1 +# #19 25.39 aarch64-binfmt-P: Could not open '/lib/ld-musl-aarch64.so.1': No such file or directory +# why exactly is it needed? where is binfmt involved? +# +RUN cp /*-alpine-linux-musl*/lib/ld-musl-*.so.1 /lib || true + RUN apk --no-cache add build-base git nodejs npm -#Setup repo COPY . ${GOPATH}/src/code.gitea.io/gitea WORKDIR ${GOPATH}/src/code.gitea.io/gitea -#Checkout version if set -RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \ - && make clean-all build - -# Begin env-to-ini build -RUN go build contrib/environment-to-ini/environment-to-ini.go +RUN make clean-all +RUN make frontend +RUN go build contrib/environment-to-ini/environment-to-ini.go && xx-verify environment-to-ini +RUN make go-check generate-backend static-executable && xx-verify gitea FROM docker.io/library/alpine:3.18 LABEL maintainer="contact@forgejo.org" diff --git a/Makefile b/Makefile index cfe10fe3e1..02db6b5514 100644 --- a/Makefile +++ b/Makefile @@ -79,31 +79,14 @@ endif STORED_VERSION_FILE := VERSION HUGO_VERSION ?= 0.111.3 -GITHUB_REF_TYPE ?= branch -GITHUB_REF_NAME ?= $(shell git rev-parse --abbrev-ref HEAD) -ifneq ($(GITHUB_REF_TYPE),branch) - VERSION ?= $(subst v,,$(GITHUB_REF_NAME)) - GITEA_VERSION ?= $(VERSION) +STORED_VERSION=$(shell cat $(STORED_VERSION_FILE) 2>/dev/null) +ifneq ($(STORED_VERSION),) + GITEA_VERSION ?= $(STORED_VERSION) else - ifneq ($(GITHUB_REF_NAME),) - VERSION ?= $(subst release/v,,$(GITHUB_REF_NAME)) - else - VERSION ?= main - endif - - STORED_VERSION=$(shell cat $(STORED_VERSION_FILE) 2>/dev/null) - ifneq ($(STORED_VERSION),) - GITEA_VERSION ?= $(STORED_VERSION) - else - GITEA_VERSION ?= $(shell git describe --tags --always | sed 's/-/+/' | sed 's/^v//') - endif -endif - -# if version = "main" then update version to "nightly" -ifeq ($(VERSION),main) - VERSION := main-nightly + GITEA_VERSION ?= $(shell git describe --tags --always | sed 's/-/+/' | sed 's/^v//') endif +VERSION = ${GITEA_VERSION} LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)" @@ -828,9 +811,15 @@ security-check: $(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ) CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@ +static-executable: $(GO_SOURCES) $(TAGS_PREREQ) + CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags 'netgo osusergo $(TAGS)' -ldflags '-s -w -linkmode external -extldflags "-static" $(LDFLAGS)' -o $(EXECUTABLE) + .PHONY: release release: frontend generate release-linux release-copy release-compress vendor release-sources release-check +# just the sources, with all assets builtin and frontend resources generated +sources-tarbal: frontend generate vendor release-sources release-check + $(DIST_DIRS): mkdir -p $(DIST_DIRS)