From a8828fbe68736c0fce10f53fb3aeff0e24824f85 Mon Sep 17 00:00:00 2001 From: nkraetzschmar <9020053+nkraetzschmar@users.noreply.github.com> Date: Wed, 18 Oct 2023 17:43:35 +0200 Subject: [PATCH] WIP --- .../{build.yml => build_container.yml} | 0 .github/workflows/build_pkg.yml | 56 ++++++++++++ build_archdep | 7 +- build_indep | 7 +- build_source | 90 ++++++++----------- gh_release | 82 +++++++++++++++++ 6 files changed, 185 insertions(+), 57 deletions(-) rename .github/workflows/{build.yml => build_container.yml} (100%) create mode 100644 .github/workflows/build_pkg.yml create mode 100755 gh_release diff --git a/.github/workflows/build.yml b/.github/workflows/build_container.yml similarity index 100% rename from .github/workflows/build.yml rename to .github/workflows/build_container.yml diff --git a/.github/workflows/build_pkg.yml b/.github/workflows/build_pkg.yml new file mode 100644 index 0000000..03aea61 --- /dev/null +++ b/.github/workflows/build_pkg.yml @@ -0,0 +1,56 @@ +name: build +on: + workflow_call: + inputs: + repository: + type: string + default: ${{ github.repository }} + ref: + type: string + default: ${{ github.sha }} + build_container: + type: string + default: ghcr.io/gardenlinux/package-build/amd64 +jobs: + source: + outputs: + pkg: ${{ steps.build.outputs.pkg }} + release: ${{ steps.release.outputs.release }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + repository: ${{ github.action_repository }} + ref: ${{ github.action_ref }} + - run: mkdir input output + - uses: actions/checkout@v4 + with: + repository: ${{ inputs.repository }} + ref: ${{ inputs.ref }} + path: input + - name: setup binfmt + run: sudo podman run --privileged ghcr.io/gardenlinux/binfmt_container + - name: pull build container + run: podman pull ${{ inputs.build_container }}:amd64 + - name: build + id: build + run: | + pkg="$(podman run --rm -v "$PWD/input:/input" -v "$PWD/output:/output" ${{ inputs.build_container }}:amd64 build_source)" + echo "pkg=$pkg" | tee "$GITHUB_OUTPUT" + - name: check if ${{ env.pkg }} already released + id: check + run: | + if ./gh_release ${{ github.token }} ${{ github.repository }} exists ${{ env.pkg }}; then + echo "skip_release=true" | tee "$GITHUB_OUTPUT" + else + echo "skip_release=false" | tee "$GITHUB_OUTPUT" + fi + - name: draft release and upload source packages + id: release + if: ${{ steps.check.outputs.skip_release != 'true' }} + run: | + release="$(./gh_release ${{ github.token }} ${{ github.repository }} create --draft "${{ steps.build.outputs.pkg }}" "${{ github.sha }}" "${{ steps.build.outputs.pkg }}")" + for f in output/*; do + ./gh_release ${{ github.token }} ${{ github.repository }} upload "$release" "$f" + done + echo "release=$release" | tee "$GITHUB_OUTPUT"b diff --git a/build_archdep b/build_archdep index 10f0f9d..63b03da 100755 --- a/build_archdep +++ b/build_archdep @@ -6,7 +6,10 @@ exec 3>&1 exec 1>&2 main() ( - dsc="$(realpath "$1")" + DEB_BUILD_OPTIONS="$(cat /input/.build_options)" + export DEB_BUILD_OPTIONS + + dsc="$(realpath "/input/.source")" dpkg_arch="$(dpkg --print-architecture)" dsc_arch="$(grep -oP '(?<=^Architecture: ).*' < "$dsc" | tr ' ' '\n')" @@ -18,7 +21,7 @@ main() ( cd src name="$(dpkg-parsechangelog --show-field Source)" version="$(dpkg-parsechangelog --show-field Version)" - DEB_BUILD_OPTIONS="terse ${DEB_BUILD_OPTIONS-}" dpkg-buildpackage --no-sign --build=any + dpkg-buildpackage --no-sign --build=any cd .. rm -rf src ls -lah diff --git a/build_indep b/build_indep index c8fc3ee..c7a7cda 100755 --- a/build_indep +++ b/build_indep @@ -6,7 +6,10 @@ exec 3>&1 exec 1>&2 main() ( - dsc="$(realpath "$1")" + DEB_BUILD_OPTIONS="$(cat /input/.build_options)" + export DEB_BUILD_OPTIONS + + dsc="$(realpath "/input/.source")" dsc_arch="$(grep -oP '(?<=^Architecture: ).*' < "$dsc" | tr ' ' '\n')" grep -P '^(linux-)?all$' <<< "$dsc_arch" || exit 0 @@ -17,7 +20,7 @@ main() ( cd src name="$(dpkg-parsechangelog --show-field Source)" version="$(dpkg-parsechangelog --show-field Version)" - DEB_BUILD_OPTIONS="terse ${DEB_BUILD_OPTIONS-}" dpkg-buildpackage --no-sign --build=all + dpkg-buildpackage --no-sign --build=all cd .. rm -rf src ls -lah diff --git a/build_source b/build_source index 7fc42d0..800725d 100755 --- a/build_source +++ b/build_source @@ -6,28 +6,11 @@ exec 3>&1 exec 1>&2 main() ( - debian_source= - while [ $# -gt 0 ]; do - case "$1" in - --debian-source) - debian_source="$2" - shift 2 - ;; - *) - break - ;; - esac - done - - source="$1" - shift - - patches=() - - while [ $# -gt 0 ]; do - patches+=("$1") - shift - done + DEB_BUILD_OPTIONS="terse $(yq -r '.build_options // ""' < "/input/pkg.yaml")" + export DEB_BUILD_OPTIONS + + source="$(yq -r '.source // ""' < "/input/pkg.yaml")" + debian_source="$(yq -r '.debian_source // ""' < "/input/pkg.yaml")" if [[ "$source" = "git+"* ]]; then git_source "${source#git+}" @@ -35,6 +18,7 @@ main() ( apt_source "$source" fi + # if debian_source defined: remove debian folder from source and replace with debian folder from debian_source if [ -n "$debian_source" ]; then mkdir debian_src cd debian_src @@ -50,15 +34,12 @@ main() ( fi cd src + apply_patches /input - for patch in "${patches[@]}"; do - apply_patches "$patch" - done - - name="$(dpkg-parsechangelog --show-field Source)" + pkg="$(dpkg-parsechangelog --show-field Source)" version="$(dpkg-parsechangelog --show-field Version)" version_orig="${version%-*}" - gzip < ../orig.tar > "../${name}_${version_orig}.orig.tar.gz" + gzip < ../orig.tar > "../${pkg}_${version_orig}.orig.tar.gz" rm ../orig.tar dpkg-source --build . @@ -67,7 +48,16 @@ main() ( rm -rf src ls -lah - echo "${name}_${version}" >&3 + echo "$DEB_BUILD_OPTIONS" > .build_options + ln -s "${pkg}_${version}.dsc" .source + + if [ -d "/output" ]; then + { echo .build_options; echo .source; echo "${pkg}_${version}.dsc"; get_files < "${pkg}_${version}.dsc"; } | while read file; do + sudo cp -d "$file" "/output/$file" + done + fi + + echo "${pkg}_${version}" >&3 ) apt_source() ( @@ -105,39 +95,33 @@ auto_decompress() ( ) apply_patches() ( - git_dir="$(realpath $(mktemp -u ../patches.tmp.XXXX))" - if [[ "$1" = "git+"* ]]; then - IFS='#' read -r url ref <<< "${1#git+}" - git clone --branch "$ref" --depth 1 "$url" "$git_dir" - dir="$git_dir" - else - dir="$(cd .. && realpath "$1")" - fi - - if [ -x "$dir/exec.pre" ]; then - SOURCE="$source" "$dir/exec.pre" + if [ -x "$1/exec.pre" ]; then + SOURCE="$source" "$1/exec.pre" fi - if [ -f "$dir/patches/series" ]; then + if [ -f "$1/patches/series" ]; then while read -r patch; do - patch -p1 < "$dir/patches/$patch" - done < "$dir/patches/series" + patch -p1 < "$1/patches/$patch" + done < "$1/patches/series" fi - version="$(yq -r .version < "$dir/changelog_config.yaml")" - [ "$version" != null ] || version="$(dpkg-parsechangelog --show-field Version)" - email="$(yq -r .email < "$dir/changelog_config.yaml")" - name="$(yq -r .name < "$dir/changelog_config.yaml")" - distribution="$(yq -r .distribution < "$dir/changelog_config.yaml")" - version_suffix="$(yq -r .version_suffix < "$dir/changelog_config.yaml")" - message="$(yq -r .message < "$dir/changelog_config.yaml")" + version="$(yq -r '.version // ""' < "$1/pkg.yaml")" + [ -n "$version" ] || version="$(dpkg-parsechangelog --show-field Version)" + email="$(yq -r '.email // ""' < "$1/pkg.yaml")" + name="$(yq -r '.name // ""' < "$1/pkg.yaml")" + distribution="$(yq -r '.distribution // ""' < "$1/pkg.yaml")" + version_suffix="$(yq -r '.version_suffix // ""' < "$1/pkg.yaml")" + message="$(yq -r '.message // ""' < "$1/pkg.yaml")" + DEBEMAIL="$email" DEBFULLNAME="$name" dch --newversion "$version$version_suffix" --distribution "$distribution" --force-distribution -- "$message" - if [ -x "$dir/exec.post" ]; then - SOURCE="$source" "$dir/exec.post" + if [ -x "$1/exec.post" ]; then + SOURCE="$source" "$1/exec.post" fi +) - [ ! -e "$git_dir" ] || rm -rf "$git_dir" +get_files() ( + awk '!/^ / { flag=0 } flag { print $NF } /^Files:/ { flag=1 }' ) main "$@" diff --git a/gh_release b/gh_release new file mode 100755 index 0000000..b74e40a --- /dev/null +++ b/gh_release @@ -0,0 +1,82 @@ +#!/bin/bash + +set -eufo pipefail + +token="$1"; shift +repo="$1"; shift + +curl_path="$(which curl)" + +function curl { + $curl_path -f -s -u "token:$token" "$@" +} + +function get { + [ $# = 1 ] + curl -X GET "https://api.github.com/repos/$repo/$1" +} + +function post { + [ $# = 2 ] + curl -X POST "https://api.github.com/repos/$repo/$1" --data "$2" +} + +function patch { + [ $# = 2 ] + curl -X PATCH "https://api.github.com/repos/$repo/$1" --data "$2" +} + +function delete { + [ $# = 1 ] + curl -X DELETE "https://api.github.com/repos/$repo/$1" +} + +function upload { + [ $# = 1 ] + curl -X POST -H "Content-Type: application/octet-stream" "https://uploads.github.com/repos/$repo/$1" --data-binary @- +} + +action="$1"; shift + +case "$action" in + "exists") + tag="$1"; shift + get "releases/tags/$tag" > /dev/null + + ;; + "create") + draft=false + if [ "$1" = "--draft" ]; then + draft=true + shift + fi + tag="$1"; shift + commit="$1"; shift + name="$1"; shift + body="$1"; shift + + release="$(post "releases" '{ + "draft": '"$draft"', + "tag_name": "'"$tag"'", + "target_commitish": "'"$commit"'", + "name": "'"$name"'" + }' | jq -r '.id')" + + echo "$release" + + ;; + "upload") + release="$1"; shift + asset_file="$1"; shift + + asset_name="$(basename "$asset_file")" + upload "releases/$release/assets?name=$asset_name" < "$asset_file" > /dev/null + echo "uploaded $asset_file to $release" + + ;; + "publish_draft") + release="$1"; shift + patch "releases/$release" '{ "draft": false }' + + ;; +esac