From f1e7ba0b94efd1cc6dc4734e4a8ddcd56d9d666e Mon Sep 17 00:00:00 2001 From: biss Date: Tue, 8 Sep 2026 20:09:55 +0800 Subject: [PATCH] workflow patch --- .gitea/workflows/build.yml | 277 ++++++++++++++++++++++++++++++++++--- 1 file changed, 258 insertions(+), 19 deletions(-) diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 8e85665..1d07641 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -1,4 +1,4 @@ -name: Build OpenWrt packages +name: Build and Release OpenWrt packages on: push: @@ -9,6 +9,12 @@ on: pull_request: workflow_dispatch: +# Gitea's built-in GITEA_TOKEN needs release write permission for tag releases. +permissions: + contents: read + actions: read + releases: write + jobs: build: runs-on: ubuntu-latest @@ -39,6 +45,25 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Resolve package version + shell: bash + run: | + set -euo pipefail + + if [ "${GITHUB_REF_TYPE}" = "tag" ]; then + VERSION="${GITHUB_REF_NAME#v}" + else + VERSION="$(sed -n 's/^PKG_VERSION:=//p' Makefile | head -n1)" + fi + + if [ -z "${VERSION}" ]; then + echo "Unable to resolve package version" + exit 1 + fi + + echo "PACKAGE_VERSION=${VERSION}" >> "${GITHUB_ENV}" + echo "Package version: ${VERSION}" + - name: Install build dependencies shell: bash run: | @@ -50,8 +75,8 @@ jobs: SUDO= fi - $SUDO apt-get update - $SUDO env DEBIAN_FRONTEND=noninteractive apt-get install -y \ + ${SUDO} apt-get update + ${SUDO} env DEBIAN_FRONTEND=noninteractive apt-get install -y \ build-essential \ clang \ flex \ @@ -72,29 +97,35 @@ jobs: zlib1g-dev \ zstd - - name: Download and verify SDK + - name: Download and verify OpenWrt SDK shell: bash run: | set -eux + wget -O "${{ matrix.sdk_file }}" "${{ matrix.sdk_url }}" echo "${{ matrix.sdk_sha256 }} ${{ matrix.sdk_file }}" | sha256sum -c - - - name: Extract SDK + - name: Extract OpenWrt SDK shell: bash run: | set -eux + rm -rf _sdk - mkdir _sdk + mkdir -p _sdk case "${{ matrix.sdk_file }}" in *.tar.zst) - tar --zstd -xf "${{ matrix.sdk_file }}" --strip-components=1 -C _sdk + tar --zstd -xf "${{ matrix.sdk_file }}" \ + --strip-components=1 \ + -C _sdk ;; *.tar.xz) - tar -xJf "${{ matrix.sdk_file }}" --strip-components=1 -C _sdk + tar -xJf "${{ matrix.sdk_file }}" \ + --strip-components=1 \ + -C _sdk ;; *) - echo "Unsupported SDK archive" + echo "Unsupported SDK archive: ${{ matrix.sdk_file }}" exit 1 ;; esac @@ -104,6 +135,7 @@ jobs: working-directory: _sdk run: | set -eux + ./scripts/feeds update luci ./scripts/feeds install luci-base @@ -111,9 +143,11 @@ jobs: shell: bash run: | set -eux + PKG="_sdk/package/luci-app-led-scheduler" - rm -rf "$PKG" - mkdir -p "$PKG" + + rm -rf "${PKG}" + mkdir -p "${PKG}" cp -a \ Makefile \ @@ -121,7 +155,15 @@ jobs: README.md \ htdocs \ root \ - "$PKG/" + "${PKG}/" + + # For tag builds, package version follows the Git tag. + # Example: v0.3.1 -> PKG_VERSION:=0.3.1 + sed -i \ + "s/^PKG_VERSION:=.*/PKG_VERSION:=${PACKAGE_VERSION}/" \ + "${PKG}/Makefile" + + grep '^PKG_VERSION:=' "${PKG}/Makefile" - name: Configure SDK shell: bash @@ -130,31 +172,228 @@ jobs: set -eux make defconfig - - name: Build + - name: Build package shell: bash working-directory: _sdk run: | set -eux - make -j"$(nproc)" package/luci-app-led-scheduler/compile V=s + + make -j"$(nproc)" \ + package/luci-app-led-scheduler/compile \ + V=s - name: Collect package shell: bash run: | set -eux + mkdir -p artifacts - find _sdk/bin -type f \ + FILE="$(find _sdk/bin -type f \ -name "luci-app-led-scheduler*.${{ matrix.format }}" \ - -exec cp -v {} artifacts/ \; + -print -quit)" - test -n "$(find artifacts -type f -name "luci-app-led-scheduler*.${{ matrix.format }}" -print -quit)" + if [ -z "${FILE}" ]; then + echo "No ${{ matrix.format }} package found" + exit 1 + fi - echo "Built for OpenWrt ${{ matrix.openwrt }}:" + ORIGINAL_NAME="$(basename "${FILE}")" + RELEASE_NAME="openwrt-${{ matrix.openwrt }}-${ORIGINAL_NAME}" + + cp -v "${FILE}" "artifacts/${RELEASE_NAME}" + + echo "Built package:" ls -lh artifacts/ - - name: Upload artifact + - name: Upload Actions artifact uses: actions/upload-artifact@v4 with: name: luci-app-led-scheduler-openwrt-${{ matrix.openwrt }}-${{ matrix.format }} path: artifacts/* if-no-files-found: error + + release: + # Ordinary pushes only build artifacts. + # A tag such as v0.3.1 additionally creates/updates a Gitea Release. + if: ${{ gitea.ref_type == 'tag' }} + needs: + - build + + runs-on: ubuntu-latest + + permissions: + contents: read + actions: read + releases: write + + steps: + - name: Download all build artifacts + uses: actions/download-artifact@v4 + with: + pattern: luci-app-led-scheduler-openwrt-* + path: release-assets + merge-multiple: true + + - name: Show release files + shell: bash + run: | + set -eux + find release-assets -maxdepth 1 -type f -print + test -n "$(find release-assets -maxdepth 1 -type f -print -quit)" + + - name: Create or update Gitea Release + id: release + shell: bash + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + run: | + set -euo pipefail + + TAG="${GITHUB_REF_NAME}" + VERSION="${TAG#v}" + API="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}" + + BODY="$(cat </tmp/release.json + elif [ "${HTTP_CODE}" = "404" ]; then + curl -fsS \ + -X POST \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "${PAYLOAD}" \ + "${API}/releases" \ + >/tmp/release.json + + RELEASE_ID="$(python3 - <<'PY' + import json + with open("/tmp/release.json", "r", encoding="utf-8") as f: + print(json.load(f)["id"]) + PY + )" + else + echo "Failed to query existing release, HTTP ${HTTP_CODE}" + cat /tmp/existing-release.json || true + exit 1 + fi + + echo "Release ID: ${RELEASE_ID}" + echo "RELEASE_ID=${RELEASE_ID}" >> "${GITHUB_ENV}" + + - name: Remove duplicate release attachments + shell: bash + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + run: | + set -euo pipefail + + API="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}" + + curl -fsS \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "${API}/releases/${RELEASE_ID}/assets" \ + >/tmp/assets.json + + python3 - <<'PY' >/tmp/delete-assets.txt + import json + from pathlib import Path + + wanted = {p.name for p in Path("release-assets").iterdir() if p.is_file()} + + with open("/tmp/assets.json", "r", encoding="utf-8") as f: + assets = json.load(f) + + for asset in assets: + if asset.get("name") in wanted: + print(asset["id"]) + PY + + while IFS= read -r ASSET_ID; do + [ -n "${ASSET_ID}" ] || continue + + echo "Removing existing attachment ID ${ASSET_ID}" + + curl -fsS \ + -X DELETE \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "${API}/releases/${RELEASE_ID}/assets/${ASSET_ID}" \ + >/dev/null + done /dev/null + done + + echo "Release assets uploaded:" + find release-assets -maxdepth 1 -type f -printf ' %f\n'