[CI] Forgejo Actions based release process
Refs: https://codeberg.org/forgejo/website/pulls/230 (cherry picked from commit87d56bf6c7
) [CI] Forgejo Actions based release process (squash) base64 -w0 to avoid wrapping when the doer name is long as it creates a broken config.json (cherry picked from commit9efdc27e49
) [CI] Forgejo Actions based release process (squash) generate .xz files and sources Generate .xz files Check .sha256 Generate the source tarbal (cherry picked from commit7afec520c4
) [CI] Forgejo Actions based release process (squash) release notes (cherry picked from commitd8f4f4807b
) [CI] Forgejo Actions based release process (squash) publish and sign release (cherry picked from commita52778c747
) (cherry picked from commitcf2ec62740
) [CI] Forgejo Actions based release process (squash) version use Actions environment variables in Makefile (#25319) (#25318) uses Actions variable to determine the version. But Forgejo builds happen in a container where they are not available. Do not use them. Also verify the version of the binary is as expected for sanity check. (cherry picked from commit6decf111a1
)
This commit is contained in:
parent
8a246d296e
commit
206d0b3886
8 changed files with 565 additions and 46 deletions
154
.forgejo/actions/build-release/action.yml
Normal file
154
.forgejo/actions/build-release/action.yml
Normal file
|
@ -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" <<EOF
|
||||||
|
insecure=true
|
||||||
|
buildx-config<<ENDVAR
|
||||||
|
[registry."${hostport}"]
|
||||||
|
http = true
|
||||||
|
ENDVAR
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Allow docker pull/push to forgejo
|
||||||
|
if: ${{ steps.registry.outputs.insecure }}
|
||||||
|
run: |-
|
||||||
|
mkdir -p /etc/docker
|
||||||
|
cat > /etc/docker/daemon.json <<EOF
|
||||||
|
{
|
||||||
|
"insecure-registries" : ["${{ steps.registry.outputs.host-port }}"],
|
||||||
|
"bip": "172.26.0.1/16"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Install docker
|
||||||
|
run: |
|
||||||
|
echo deb http://deb.debian.org/debian bullseye-backports main | tee /etc/apt/sources.list.d/backports.list && apt-get -qq update
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -qq -y -t bullseye-backports docker.io
|
||||||
|
|
||||||
|
- uses: https://github.com/docker/setup-buildx-action@v2
|
||||||
|
with:
|
||||||
|
config-inline: |
|
||||||
|
${{ steps.registry.outputs.buildx-config }}
|
||||||
|
|
||||||
|
- name: Login to the container registry
|
||||||
|
run: |
|
||||||
|
BASE64_AUTH=`echo -n "${{ inputs.doer }}:${{ inputs.token }}" | base64 -w0`
|
||||||
|
mkdir -p ~/.docker
|
||||||
|
echo "{\"auths\": {\"$CI_REGISTRY\": {\"auth\": \"$BASE64_AUTH\"}}}" > ~/.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 is converted with - sometime changed into +, 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 }}
|
93
.forgejo/actions/publish-release/action.yml
Normal file
93
.forgejo/actions/publish-release/action.yml
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
name: 'Publish release'
|
||||||
|
author: 'Forgejo authors'
|
||||||
|
description: |
|
||||||
|
Publish release
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
forgejo:
|
||||||
|
description: 'URL of the Forgejo instance where the release is uploaded'
|
||||||
|
required: true
|
||||||
|
from-owner:
|
||||||
|
description: 'the owner from which a release is to be copied'
|
||||||
|
required: true
|
||||||
|
to-owner:
|
||||||
|
description: 'the owner to which a release is to be copied'
|
||||||
|
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'
|
||||||
|
required: true
|
||||||
|
doer:
|
||||||
|
description: 'Name of the user authoring the release'
|
||||||
|
required: true
|
||||||
|
token:
|
||||||
|
description: 'application token on FORGEJO with permission to the repository and the packages'
|
||||||
|
required: true
|
||||||
|
gpg-private-key:
|
||||||
|
description: 'GPG Private Key to sign the release artifacts'
|
||||||
|
gpg-passphrase:
|
||||||
|
description: 'Passphrase of the GPG Private Key'
|
||||||
|
|
||||||
|
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: apt-get install docker.io
|
||||||
|
run: |
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -qq -y docker.io
|
||||||
|
|
||||||
|
- name: download release
|
||||||
|
uses: https://code.forgejo.org/actions/forgejo-release@v1
|
||||||
|
with:
|
||||||
|
url: ${{ inputs.forgejo }}
|
||||||
|
repo: ${{ inputs.from-owner }}/${{ inputs.repo }}
|
||||||
|
direction: download
|
||||||
|
release-dir: release
|
||||||
|
download-retry: 60
|
||||||
|
token: ${{ inputs.token }}
|
||||||
|
|
||||||
|
- name: upload release
|
||||||
|
uses: https://code.forgejo.org/actions/forgejo-release@v1
|
||||||
|
with:
|
||||||
|
url: ${{ inputs.forgejo }}
|
||||||
|
repo: ${{ inputs.to-owner }}/${{ inputs.repo }}
|
||||||
|
direction: upload
|
||||||
|
release-dir: release
|
||||||
|
release-notes: "See https://codeberg.org/forgejo/forgejo/src/branch/forgejo/RELEASE-NOTES.md#${{ steps.tag-version.outputs.value }}"
|
||||||
|
token: ${{ inputs.token }}
|
||||||
|
gpg-private-key: ${{ inputs.gpg-private-key }}
|
||||||
|
gpg-passphrase: ${{ inputs.gpg-passphrase }}
|
||||||
|
|
||||||
|
- name: login to the registry
|
||||||
|
uses: https://github.com/docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: ${{ steps.hostport.outputs.value }}
|
||||||
|
username: ${{ inputs.doer }}
|
||||||
|
password: ${{ inputs.token }}
|
||||||
|
|
||||||
|
- uses: https://code.forgejo.org/forgejo/forgejo-container-image@v1
|
||||||
|
env:
|
||||||
|
VERIFY: 'false'
|
||||||
|
with:
|
||||||
|
url: https://${{ steps.hostport.outputs.value }}
|
||||||
|
destination-owner: ${{ inputs.to-owner }}
|
||||||
|
owner: ${{ inputs.from-owner }}
|
||||||
|
suffixes: '-rootless'
|
||||||
|
project: ${{ inputs.repo }}
|
||||||
|
tag: ${{ steps.tag-version.outputs.value }}
|
||||||
|
doer: ${{ inputs.doer }}
|
||||||
|
token: ${{ inputs.token }}
|
104
.forgejo/workflows/build-release-integration.yml
Normal file
104
.forgejo/workflows/build-release-integration.yml
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
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 <<EOF
|
||||||
|
{
|
||||||
|
"insecure-registries" : ["${{ steps.forgejo.outputs.host-port }}"]
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
systemctl restart docker
|
||||||
|
|
||||||
|
apt-get install -qq -y xz-utils
|
||||||
|
|
||||||
|
dir=$(mktemp -d)
|
||||||
|
trap "rm -fr $dir" EXIT
|
||||||
|
|
||||||
|
url=http://root:admin1234@${{ steps.forgejo.outputs.host-port }}
|
||||||
|
export FORGEJO_RUNNER_LOGS="${{ steps.forgejo.outputs.runner-logs }}"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Create a new project with a fake forgejo and the release workflow only
|
||||||
|
#
|
||||||
|
mkdir -p $dir/.forgejo/workflows
|
||||||
|
cp .forgejo/workflows/build-release.yml $dir/.forgejo/workflows
|
||||||
|
cp -a .forgejo/actions $dir/.forgejo/actions
|
||||||
|
cat > $dir/Dockerfile <<EOF
|
||||||
|
FROM docker.io/library/alpine:3.18
|
||||||
|
RUN mkdir -p /app/gitea
|
||||||
|
RUN ( echo '#!/bin/sh' ; echo "echo forgejo v$version" ) > /app/gitea/gitea ; chmod +x /app/gitea/gitea
|
||||||
|
EOF
|
||||||
|
cp $dir/Dockerfile $dir/Dockerfile.rootless
|
||||||
|
sources=forgejo-src-$version.tar.gz
|
||||||
|
( echo 'sources-tarbal:' ; echo -e '\tmkdir -p dist/release ; cd dist/release ; sources=forgejo-src-$(VERSION).tar.gz ; echo sources > $$sources ; shasum -a 256 $$sources > $$sources.sha256' ) > $dir/Makefile
|
||||||
|
|
||||||
|
forgejo-test-helper.sh push $dir $url root forgejo |& tee $dir/pushed
|
||||||
|
eval $(grep '^sha=' < $dir/pushed)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Push a tag to trigger the release workflow and wait for it to complete
|
||||||
|
#
|
||||||
|
forgejo-test-helper.sh api POST $url repos/root/forgejo/tags ${{ steps.forgejo.outputs.token }} --data-raw '{"tag_name": "v'$version'", "target": "'$sha'"}'
|
||||||
|
LOOPS=180 forgejo-test-helper.sh wait_success "$url" root/forgejo $sha
|
||||||
|
|
||||||
|
#
|
||||||
|
# uncomment to see the logs even when everything is reported to be working ok
|
||||||
|
#
|
||||||
|
#cat $FORGEJO_RUNNER_LOGS
|
||||||
|
|
||||||
|
#
|
||||||
|
# Minimal sanity checks. e2e test is for the setup-forgejo
|
||||||
|
# action and the infrastructure playbook. Since the binary
|
||||||
|
# is a script shell it does not test the sanity of the cross
|
||||||
|
# build, only the sanity of the naming of the binaries.
|
||||||
|
#
|
||||||
|
for arch in amd64 arm64 arm-6 ; do
|
||||||
|
binary=forgejo-$version-linux-$arch
|
||||||
|
for suffix in '' '.xz' ; do
|
||||||
|
curl --fail -L -sS $url/root/forgejo/releases/download/v$version/$binary$suffix > $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
|
||||||
|
|
||||||
|
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
|
134
.forgejo/workflows/build-release.yml
Normal file
134
.forgejo/workflows/build-release.yml
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
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" <<EOF
|
||||||
|
value<<ENDVAR
|
||||||
|
See https://codeberg.org/forgejo/forgejo/src/branch/forgejo/RELEASE-NOTES.md#${{ steps.tag-version.outputs.value }}
|
||||||
|
ENDVAR
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Build sources
|
||||||
|
run: |
|
||||||
|
apt-get -qq install -y make
|
||||||
|
make VERSION=${{ steps.tag-version.outputs.value }} sources-tarbal
|
||||||
|
mv dist/release release
|
||||||
|
find release | grep tar.gz # sanity check to fail fast
|
||||||
|
|
||||||
|
- 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 }}
|
25
.forgejo/workflows/publish-release.yml
Normal file
25
.forgejo/workflows/publish-release.yml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
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:
|
||||||
|
- 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 }}
|
35
Dockerfile
35
Dockerfile
|
@ -1,5 +1,6 @@
|
||||||
#Build stage
|
FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx
|
||||||
FROM docker.io/library/golang:1.20-alpine3.18 AS build-env
|
|
||||||
|
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.20-alpine3.18 as build-env
|
||||||
|
|
||||||
ARG GOPROXY
|
ARG GOPROXY
|
||||||
ENV GOPROXY ${GOPROXY:-direct}
|
ENV GOPROXY ${GOPROXY:-direct}
|
||||||
|
@ -9,19 +10,33 @@ ARG TAGS="sqlite sqlite_unlock_notify"
|
||||||
ENV TAGS "bindata timetzdata $TAGS"
|
ENV TAGS "bindata timetzdata $TAGS"
|
||||||
ARG CGO_EXTRA_CFLAGS
|
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
|
RUN apk --no-cache add build-base git nodejs npm
|
||||||
|
|
||||||
#Setup repo
|
|
||||||
COPY . ${GOPATH}/src/code.gitea.io/gitea
|
COPY . ${GOPATH}/src/code.gitea.io/gitea
|
||||||
WORKDIR ${GOPATH}/src/code.gitea.io/gitea
|
WORKDIR ${GOPATH}/src/code.gitea.io/gitea
|
||||||
|
|
||||||
#Checkout version if set
|
RUN make clean-all
|
||||||
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
RUN make frontend
|
||||||
&& make clean-all build
|
RUN go build contrib/environment-to-ini/environment-to-ini.go && xx-verify environment-to-ini
|
||||||
|
RUN make backend && xx-verify gitea
|
||||||
# Begin env-to-ini build
|
|
||||||
RUN go build contrib/environment-to-ini/environment-to-ini.go
|
|
||||||
|
|
||||||
FROM docker.io/library/alpine:3.18
|
FROM docker.io/library/alpine:3.18
|
||||||
LABEL maintainer="contact@forgejo.org"
|
LABEL maintainer="contact@forgejo.org"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#Build stage
|
FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx
|
||||||
FROM docker.io/library/golang:1.20-alpine3.18 AS build-env
|
|
||||||
|
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.20-alpine3.18 as build-env
|
||||||
|
|
||||||
ARG GOPROXY
|
ARG GOPROXY
|
||||||
ENV GOPROXY ${GOPROXY:-direct}
|
ENV GOPROXY ${GOPROXY:-direct}
|
||||||
|
@ -9,19 +10,33 @@ ARG TAGS="sqlite sqlite_unlock_notify"
|
||||||
ENV TAGS "bindata timetzdata $TAGS"
|
ENV TAGS "bindata timetzdata $TAGS"
|
||||||
ARG CGO_EXTRA_CFLAGS
|
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
|
RUN apk --no-cache add build-base git nodejs npm
|
||||||
|
|
||||||
#Setup repo
|
|
||||||
COPY . ${GOPATH}/src/code.gitea.io/gitea
|
COPY . ${GOPATH}/src/code.gitea.io/gitea
|
||||||
WORKDIR ${GOPATH}/src/code.gitea.io/gitea
|
WORKDIR ${GOPATH}/src/code.gitea.io/gitea
|
||||||
|
|
||||||
#Checkout version if set
|
RUN make clean-all
|
||||||
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
RUN make frontend
|
||||||
&& make clean-all build
|
RUN go build contrib/environment-to-ini/environment-to-ini.go && xx-verify environment-to-ini
|
||||||
|
RUN make backend && xx-verify gitea
|
||||||
# Begin env-to-ini build
|
|
||||||
RUN go build contrib/environment-to-ini/environment-to-ini.go
|
|
||||||
|
|
||||||
FROM docker.io/library/alpine:3.18
|
FROM docker.io/library/alpine:3.18
|
||||||
LABEL maintainer="contact@forgejo.org"
|
LABEL maintainer="contact@forgejo.org"
|
||||||
|
|
29
Makefile
29
Makefile
|
@ -79,31 +79,8 @@ endif
|
||||||
STORED_VERSION_FILE := VERSION
|
STORED_VERSION_FILE := VERSION
|
||||||
HUGO_VERSION ?= 0.111.3
|
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 ?= $(GITHUB_REF_NAME)
|
|
||||||
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//')
|
GITEA_VERSION ?= $(shell git describe --tags --always | sed 's/-/+/' | sed 's/^v//')
|
||||||
endif
|
VERSION = ${GITEA_VERSION}
|
||||||
endif
|
|
||||||
|
|
||||||
# if version = "main" then update version to "nightly"
|
|
||||||
ifeq ($(VERSION),main)
|
|
||||||
VERSION := main-nightly
|
|
||||||
endif
|
|
||||||
|
|
||||||
LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)"
|
LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)"
|
||||||
|
|
||||||
|
@ -825,11 +802,13 @@ security-check:
|
||||||
go run $(GOVULNCHECK_PACKAGE) ./...
|
go run $(GOVULNCHECK_PACKAGE) ./...
|
||||||
|
|
||||||
$(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ)
|
$(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ)
|
||||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
|
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags 'netgo osusergo $(TAGS)' -ldflags '-s -w -linkmode external -extldflags "-static" $(LDFLAGS)' -o $@
|
||||||
|
|
||||||
.PHONY: release
|
.PHONY: release
|
||||||
release: frontend generate release-linux release-copy release-compress vendor release-sources release-check
|
release: frontend generate release-linux release-copy release-compress vendor release-sources release-check
|
||||||
|
|
||||||
|
sources-tarbal: vendor release-sources release-check
|
||||||
|
|
||||||
$(DIST_DIRS):
|
$(DIST_DIRS):
|
||||||
mkdir -p $(DIST_DIRS)
|
mkdir -p $(DIST_DIRS)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue