# # Copyright (C) 2022 Ing # # This is free software, licensed under the MIT License. # See /LICENSE for more information. # name: Issues on: issues: types: [opened, reopened] jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@main - name: Init Env run: | git config --global user.email "github-actions[bot]@users.noreply.github.com" git config --global user.name "github-actions[bot]" sudo timedatectl set-timezone "Asia/Shanghai" - name: Check Issues shell: python run: | # -*- coding: utf-8 -*- import json, subprocess def set_output(name, value): subprocess.call(["echo '{}={}' >> $GITHUB_ENV".format(name, value)], shell=True) issuetitle = ${{ toJSON(github.event.issue.title) }} issuebody = ${{ toJSON(github.event.issue.body) }} iscustom = 'false' warinfo = 'false' format = '' language= '' model = '' version = '' kernel = '' addons = '' modules = '' try: if issuetitle.lower().startswith('custom'): jsonbody = json.loads(issuebody) iscustom = 'true' format = jsonbody.get('format', '') language = jsonbody.get('language', '') model = jsonbody.get('model', '') version = jsonbody.get('version', '') kernel = jsonbody.get('kernel', '') addons = jsonbody.get('addons', '') modules = jsonbody.get('modules', '') except ValueError as e: pass if iscustom == 'false': if issuebody.find('DMI') < 0 and issuebody.find('CPU') < 0 and issuebody.find('NIC') < 0: warinfo = 'true' set_output("iscustom", iscustom) set_output("warinfo", warinfo) set_output("format", format) set_output("language", language) set_output("model", model) set_output("version", version) set_output("kernel", kernel) set_output("addons", addons) set_output("modules", modules) - name: Update Comment Warinfo if: env.warinfo == 'true' uses: actions-cool/issues-helper@v3 with: actions: "create-comment" token: ${{ secrets.GITHUB_TOKEN }} issue-number: ${{ github.event.issue.number }} body: | 请填写以下信息. Please fill in the following information. Install ENV: (You can find it in the boot interface.) * DMI: * CPU: * NIC: (pid & vid) RR version: (You can find it in the update menu.) * RR: * addons: * modules: * lkms: DSM: * model: * version: Issue: logs: (## 因为 log中存在 SN/MAC 等一些敏感信息, 当提供完整文件时请自行抹除他们, 当然你也可以发送到我的邮箱. ##) (## Because the log contains some sensitive information such as SN/MAC, please delete them when providing the complete file. Of course, you can also send it to my email. ##) ... (请先看一下#173、#175、#226 的内容) (Plz review the content of #173, #175, #226 first) ... (如果你只是说 XXX 不能用, 什么详细信息也不提供, 我也只能说感谢你的反馈.) (If you just say XXX doesn't work without providing any details, I can only say thank you for your feedback.) ... emoji: heart - name: Update Comment Labels if: env.iscustom == 'true' uses: actions-cool/issues-helper@v3 with: actions: 'add-labels' token: ${{ secrets.GITHUB_TOKEN }} issue-number: ${{ github.event.issue.number }} labels: 'custom,${{ env.model }}' - name: Update Comment Building if: env.iscustom == 'true' id: comment uses: actions-cool/issues-helper@v3 with: actions: 'create-comment' token: ${{ secrets.GITHUB_TOKEN }} issue-number: ${{ github.event.issue.number }} body: | Hi @${{ github.event.issue.user.login }}. RR-${{ env.model }} building (Usually about 5 minutes) ... > ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} ---- emoji: heart - name: Run Build if: env.iscustom == 'true' run: | # 累了, 毁灭吧! # yq need sudo !!! function deleteConfigKey() { sudo yq eval "del(.${1})" --inplace "${2}" 2>/dev/null } function writeConfigKey() { local value="${2}" [ "${value}" = "{}" ] && sudo yq eval ".${1} = {}" --inplace "${3}" 2>/dev/null || sudo yq eval ".${1} = \"${value}\"" --inplace "${3}" 2>/dev/null } function readConfigKey() { local result=$(sudo yq eval ".${1} | explode(.)" "${2}" 2>/dev/null) [ "${result}" = "null" ] && echo "" || echo "${result}" } function mergeConfigModules() { # Error: bad file '-': cannot index array with '8139cp' (strconv.ParseInt: parsing "8139cp": invalid syntax) # When the first key is a pure number, yq will not process it as a string by default. The current solution is to insert a placeholder key. local MS="RRORG\n${1// /\\n}" local L="$(echo -en "${MS}" | awk '{print "modules."$1":"}')" local xmlfile=$(mktemp) echo -en "${L}" | sudo yq -p p -o y >"${xmlfile}" deleteConfigKey "modules.\"RRORG\"" "${xmlfile}" sudo yq eval-all --inplace '. as $item ireduce ({}; . * $item)' --inplace "${2}" "${xmlfile}" 2>/dev/null rm -f "${xmlfile}" } REPO="${{ github.server_url }}/${{ github.repository }}" MODEL="${{ env.model }}" VERSION="${{ env.version }}" PRERELEASE="true" TAG="" if [ "${PRERELEASE}" = "true" ]; then TAG="$(curl -skL --connect-timeout 10 "${REPO}/tags" | grep "/refs/tags/.*\.zip" | sed -E 's/.*\/refs\/tags\/(.*)\.zip.*$/\1/' | sort -rV | head -1)" else LATESTURL="$(curl -skL --connect-timeout 10 -w %{url_effective} -o /dev/null "${REPO}/releases/latest")" TAG="${LATESTURL##*/}" fi [ "${TAG:0:1}" = "v" ] && TAG="${TAG:1}" rm -f rr-${TAG}.img.zip STATUS=$(curl -kL --connect-timeout 10 -w "%{http_code}" "${REPO}/releases/download/${TAG}/rr-${TAG}.img.zip" -o "rr-${TAG}.img.zip") if [ $? -ne 0 ] || [ ${STATUS:-0} -ne 200 ]; then echo "Download failed" exit 1 fi unzip rr-${TAG}.img.zip -d "rr" export TERM=xterm sudo ./localbuild.sh create rr/ws rr/rr.img if [ $? -ne 0 ]; then echo "create failed" exit 1 fi # sudo cp -rf files/initrd/opt/rr/* rr/ws/initrd/opt/rr/ # sudo sed -i "s/set -e/set -ex/" rr/ws/initrd/opt/rr/init.sh # sudo sed -i '/^alias/i\set -x' rr/ws/initrd/opt/rr/menu.sh [ -n "${{ env.language }}" ] && echo "${{ env.language }}.UTF-8" | sudo tee rr/ws/mnt/p1/.locale sudo ./localbuild.sh init if [ $? -ne 0 ]; then echo "init failed" exit 1 fi if [ -n "${{ env.kernel }}" ]; then echo "set kernel" USER_CONFIG_FILE="rr/ws/mnt/p1/user-config.yml" writeConfigKey "kernel" "${{ env.kernel }}" "${USER_CONFIG_FILE}" fi sudo ./localbuild.sh config "${MODEL}" "${VERSION}" if [ $? -ne 0 ]; then echo "config failed" exit 1 fi if [ -n "${{ env.addons }}" ]; then echo "set addons: ${{ env.addons }}" USER_CONFIG_FILE="rr/ws/mnt/p1/user-config.yml" writeConfigKey "addons" "{}" "${USER_CONFIG_FILE}" for A in $(echo "${{ env.addons }}" | sed 's/,/ /g'); do writeConfigKey "addons.\"${A}\"" "" "${USER_CONFIG_FILE}" done fi if [ ! "custom" = "${{ env.kernel }}" ] && [ -n "${{ env.modules }}" ]; then echo "set modules: ${{ env.modules }}" USER_CONFIG_FILE="rr/ws/mnt/p1/user-config.yml" writeConfigKey "modules" "{}" "${USER_CONFIG_FILE}" mergeConfigModules "$(echo "${{ env.modules }}" | sed 's/,/\n/g')" "${USER_CONFIG_FILE}" # for M in $(echo "${{ env.modules }}" | sed 's/,/ /g'); do # writeConfigKey "modules.\"${M}\"" "" "${USER_CONFIG_FILE}" # done fi sudo ./localbuild.sh build if [ $? -ne 0 ]; then echo "build failed" exit 1 fi sudo ./localbuild.sh pack rr/rr.img if [ $? -ne 0 ]; then echo "pack failed" exit 1 fi ls rr -al RR_VERSION_FILE="rr/ws/mnt/p1/RR_VERSION" USER_CONFIG_FILE="rr/ws/mnt/p1/user-config.yml" { echo "RR: " echo " VERSION: $(cat ${RR_VERSION_FILE} 2>/dev/null | head -1)" echo " CUSTOM: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" echo echo "DSM:" echo " MODEL: $(readConfigKey "model" "${USER_CONFIG_FILE}")" echo " VERSION: $(readConfigKey "productver" "${USER_CONFIG_FILE}")" echo " KERNEL: $(readConfigKey "kernel" "${USER_CONFIG_FILE}")" echo " PATURL: $(readConfigKey "paturl" "${USER_CONFIG_FILE}")" echo " PATSUM: $(readConfigKey "patsum" "${USER_CONFIG_FILE}")" echo echo echo "After the image is written to the disk, it will boot directly into DSM without the need to compile again." echo "Of course, you can also modify the settings yourself." } >README.txt if [ "${{ env.format }}" = "ova" ]; then . scripts/func.sh "${{ secrets.RRORG }}" convertova "rr/rr.img" "rr/rr.ova" (cd rr; sha256sum rr.ova >../sha256sum) zip -9 "rr-${MODEL}-${TAG}-${{ github.run_id }}.ova.zip" -j rr/rr.ova ${USER_CONFIG_FILE} sha256sum README.txt elif [ "${{ env.format }}" = "vmx" ]; then . scripts/func.sh "${{ secrets.RRORG }}" convertvmx "rr/rr.img" "rr.vmx" # rr.vmx is a directory (cd rr.vmx; sha256sum * >../sha256sum) zip -9 "rr-${MODEL}-${TAG}-${{ github.run_id }}.vmx.zip" -r rr.vmx ${USER_CONFIG_FILE} sha256sum README.txt elif [ "${{ env.format }}" = "vmdk" ]; then qemu-img convert rr/rr.img -O vmdk -o 'adapter_type=lsilogic,subformat=streamOptimized,compat6' rr/rr.vmdk (cd rr; sha256sum rr.vmdk >../sha256sum) zip -9 "rr-${MODEL}-${TAG}-${{ github.run_id }}.vmdk.zip" -j rr/rr.vmdk ${USER_CONFIG_FILE} sha256sum README.txt elif [ "${{ env.format }}" = "flat" ]; then qemu-img convert rr/rr.img -O vmdk -o 'adapter_type=lsilogic,subformat=monolithicFlat,compat6' rr/rr.vmdk (cd rr; sha256sum rr*.vmdk >../sha256sum) zip -9 "rr-${MODEL}-${TAG}-${{ github.run_id }}.flat.zip" -j rr/rr*.vmdk ${USER_CONFIG_FILE} sha256sum README.txt elif [ "${{ env.format }}" = "vhd" ]; then . scripts/func.sh "${{ secrets.RRORG }}" qemu-img convert rr/rr.img -O vpc rr/rr.vhd createvmc "rr/rr.vhd" "rr/rr.vmc" (cd rr; sha256sum rr.vhd >../sha256sum) zip -9 "rr-${MODEL}-${TAG}-${{ github.run_id }}.vhd.zip" -j rr/rr.vmc rr/rr.vhd ${USER_CONFIG_FILE} sha256sum README.txt elif [ "${{ env.format }}" = "vhdx" ]; then qemu-img convert rr/rr.img -O vhdx -o subformat=dynamic rr/rr.vhdx (cd rr; sha256sum rr.vhdx >../sha256sum) zip -9 "rr-${MODEL}-${TAG}-${{ github.run_id }}.vhdx.zip" -j rr/rr.vhdx ${USER_CONFIG_FILE} sha256sum README.txt else (cd rr; sha256sum rr.img >../sha256sum) zip -9 "rr-${MODEL}-${TAG}-${{ github.run_id }}.img.zip" -j rr/rr.img ${USER_CONFIG_FILE} sha256sum README.txt fi echo "TAG=${TAG}" >> $GITHUB_ENV - name: Upload to Artifacts if: env.iscustom == 'true' && success() uses: actions/upload-artifact@v4 with: name: rr-${{ env.model }}-${{ env.TAG }} path: | rr-${{ env.model }}-${{ env.TAG }}*.zip retention-days: 5 - name: Update Comment Success if: env.iscustom == 'true' && success() uses: actions-cool/issues-helper@v3 with: actions: 'update-comment' token: ${{ secrets.GITHUB_TOKEN }} comment-id: ${{ steps.comment.outputs.comment-id }} update-mode: replace body: | Hi @${{ github.event.issue.user.login }}. RR-${{ env.model }} build success, please download the attachment from the below link (Attachments are only kept for 5 days). > ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} ---- emoji: hooray - name: Close Issues if: env.iscustom == 'true' && success() uses: actions-cool/issues-helper@v3 with: actions: 'close-issue' token: ${{ secrets.GITHUB_TOKEN }} issue-number: ${{ github.event.issue.number }} - name: Update Comment Fail if: env.iscustom == 'true' && failure() uses: actions-cool/issues-helper@v3 with: actions: 'update-comment' token: ${{ secrets.GITHUB_TOKEN }} comment-id: ${{ steps.comment.outputs.comment-id }} update-mode: replace body: | Hi @${{ github.event.issue.user.login }}. RR-${{ env.model }} build failed, please try again. > ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} ---- emoji: confused