Skip to content

Commit f724ebe

Browse files
committed
test: Optimize CI/CD test workflow
1 parent 4be7eda commit f724ebe

6 files changed

Lines changed: 361 additions & 2 deletions

File tree

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
name: Build and Publish to AUR
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'pkgs/*/PKGBUILD'
9+
- 'pkgs/*/.SRCINFO'
10+
workflow_dispatch:
11+
inputs:
12+
package:
13+
description: 'Package to build and publish'
14+
required: true
15+
type: string
16+
skip_publish:
17+
description: 'Skip AUR publishing (dry-run)'
18+
required: false
19+
type: boolean
20+
default: false
21+
22+
permissions:
23+
contents: read
24+
25+
jobs:
26+
detect-changed-packages:
27+
runs-on: ubuntu-latest
28+
outputs:
29+
packages: ${{ steps.detect.outputs.packages }}
30+
steps:
31+
- name: Checkout repository
32+
uses: actions/checkout@v4
33+
with:
34+
fetch-depth: 2
35+
36+
- name: Detect changed packages
37+
id: detect
38+
run: |
39+
set -euo pipefail
40+
41+
if [[ -n "${{ github.event.inputs.package }}" ]]; then
42+
echo "packages=[\"${{ github.event.inputs.package }}\"]" >> "${GITHUB_OUTPUT}"
43+
exit 0
44+
fi
45+
46+
# Detect packages with PKGBUILD or .SRCINFO changes
47+
changed_files=$(git diff --name-only HEAD^ HEAD || git diff --name-only HEAD)
48+
packages=$(echo "${changed_files}" | grep -E '^pkgs/[^/]+/(PKGBUILD|\.SRCINFO)$' | cut -d'/' -f2 | sort -u | jq -R -s -c 'split("\n")[:-1]')
49+
50+
if [[ "${packages}" == "[]" || -z "${packages}" ]]; then
51+
echo "No package changes detected"
52+
echo "packages=[]" >> "${GITHUB_OUTPUT}"
53+
else
54+
echo "Detected package changes: ${packages}"
55+
echo "packages=${packages}" >> "${GITHUB_OUTPUT}"
56+
fi
57+
58+
build-and-validate:
59+
needs: detect-changed-packages
60+
if: needs.detect-changed-packages.outputs.packages != '[]'
61+
runs-on: ubuntu-latest
62+
strategy:
63+
matrix:
64+
package: ${{ fromJson(needs.detect-changed-packages.outputs.packages) }}
65+
fail-fast: false
66+
steps:
67+
- name: Checkout repository
68+
uses: actions/checkout@v4
69+
70+
- name: Build and validate package
71+
uses: heyhusen/archlinux-package-action@v2
72+
with:
73+
path: pkgs/${{ matrix.package }}
74+
flags: '-s --noconfirm'
75+
namcap: true
76+
srcinfo: true
77+
78+
- name: Upload build artifacts
79+
uses: actions/upload-artifact@v4
80+
with:
81+
name: ${{ matrix.package }}-${{ github.run_id }}
82+
path: |
83+
pkgs/${{ matrix.package }}/*.pkg.tar.zst
84+
pkgs/${{ matrix.package }}/*.pkg.tar.zst.sig
85+
retention-days: 90
86+
87+
- name: Upload build logs
88+
if: always()
89+
uses: actions/upload-artifact@v4
90+
with:
91+
name: ${{ matrix.package }}-logs-${{ github.run_id }}
92+
path: |
93+
pkgs/${{ matrix.package }}/*.log
94+
pkgs/${{ matrix.package }}/src/
95+
retention-days: 30
96+
if-no-files-found: ignore
97+
98+
publish-to-aur:
99+
needs: [detect-changed-packages, build-and-validate]
100+
if: needs.detect-changed-packages.outputs.packages != '[]' && github.event.inputs.skip_publish != 'true'
101+
runs-on: ubuntu-latest
102+
strategy:
103+
matrix:
104+
package: ${{ fromJson(needs.detect-changed-packages.outputs.packages) }}
105+
fail-fast: false
106+
steps:
107+
- name: Checkout repository
108+
uses: actions/checkout@v4
109+
110+
- name: Get package version
111+
id: pkgver
112+
run: |
113+
pkg_dir="pkgs/${{ matrix.package }}"
114+
pkgver=$(awk -F'= *' '$1=="pkgver"{print $2; exit}' "${pkg_dir}/PKGBUILD")
115+
echo "version=${pkgver}" >> "${GITHUB_OUTPUT}"
116+
117+
- name: Publish to AUR
118+
uses: KSXGitHub/github-actions-deploy-aur@v2.7.0
119+
with:
120+
pkgname: ${{ matrix.package }}
121+
pkgbuild: pkgs/${{ matrix.package }}/PKGBUILD
122+
commit_username: github-actions[bot]
123+
commit_email: github-actions[bot]@users.noreply.github.com
124+
ssh_private_key: ${{ secrets.AUR_SSH_KEY }}
125+
commit_message: |
126+
Update to ${{ steps.pkgver.outputs.version }}
127+
128+
Automated build and publish via GitHub Actions.
129+
130+
Co-Authored-By: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
131+
assets: |
132+
pkgs/${{ matrix.package }}/.SRCINFO
133+
pkgs/${{ matrix.package }}/*.install
134+
pkgs/${{ matrix.package }}/*.patch
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
name: Monitor Upstream Releases
2+
3+
on:
4+
schedule:
5+
# Run daily at 00:00 UTC
6+
- cron: '0 0 * * *'
7+
workflow_dispatch:
8+
inputs:
9+
package:
10+
description: 'Specific package to check (leave empty for all)'
11+
required: false
12+
type: string
13+
force:
14+
description: 'Force update even if version unchanged'
15+
required: false
16+
type: boolean
17+
default: false
18+
19+
permissions:
20+
contents: write
21+
22+
jobs:
23+
detect-updates:
24+
runs-on: ubuntu-latest
25+
steps:
26+
- name: Checkout repository
27+
uses: actions/checkout@v4
28+
with:
29+
fetch-depth: 0
30+
31+
- name: Configure Git
32+
run: |
33+
git config user.name "github-actions[bot]"
34+
git config user.email "github-actions[bot]@users.noreply.github.com"
35+
36+
- name: Install dependencies
37+
run: |
38+
sudo apt-get update
39+
sudo apt-get install -y curl jq
40+
41+
- name: Discover packages
42+
id: discover
43+
run: |
44+
if [[ -n "${{ github.event.inputs.package }}" ]]; then
45+
echo "packages=${{ github.event.inputs.package }}" >> "${GITHUB_OUTPUT}"
46+
else
47+
packages=$(find pkgs -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | sort | jq -R -s -c 'split("\n")[:-1]')
48+
echo "packages=${packages}" >> "${GITHUB_OUTPUT}"
49+
fi
50+
51+
- name: Check for updates
52+
run: |
53+
set -euo pipefail
54+
55+
packages='${{ steps.discover.outputs.packages }}'
56+
force_flag=""
57+
if [[ "${{ github.event.inputs.force }}" == "true" ]]; then
58+
force_flag="--force"
59+
fi
60+
61+
updated_packages=()
62+
63+
if [[ "${packages}" == *"["* ]]; then
64+
# JSON array from discovery
65+
for pkg in $(echo "${packages}" | jq -r '.[]'); do
66+
echo "Checking ${pkg}..."
67+
if scripts/update-package.sh "${pkg}" ${force_flag}; then
68+
if git diff --quiet "pkgs/${pkg}/PKGBUILD" "pkgs/${pkg}/.SRCINFO" 2>/dev/null; then
69+
echo "No changes detected for ${pkg}"
70+
else
71+
echo "Updates detected for ${pkg}"
72+
updated_packages+=("${pkg}")
73+
fi
74+
else
75+
echo "Failed to check ${pkg}" >&2
76+
fi
77+
done
78+
else
79+
# Single package from manual input
80+
pkg="${packages}"
81+
echo "Checking ${pkg}..."
82+
if scripts/update-package.sh "${pkg}" ${force_flag}; then
83+
if git diff --quiet "pkgs/${pkg}/PKGBUILD" "pkgs/${pkg}/.SRCINFO" 2>/dev/null; then
84+
echo "No changes detected for ${pkg}"
85+
else
86+
echo "Updates detected for ${pkg}"
87+
updated_packages+=("${pkg}")
88+
fi
89+
else
90+
echo "Failed to check ${pkg}" >&2
91+
exit 1
92+
fi
93+
fi
94+
95+
if [[ ${#updated_packages[@]} -eq 0 ]]; then
96+
echo "No package updates to commit"
97+
exit 0
98+
fi
99+
100+
# Regenerate README with updated package versions
101+
echo "Regenerating README files..."
102+
bash scripts/build-readme.sh
103+
104+
# Commit updates
105+
for pkg in "${updated_packages[@]}"; do
106+
git add "pkgs/${pkg}/PKGBUILD" "pkgs/${pkg}/.SRCINFO"
107+
108+
# Extract version from PKGBUILD
109+
new_version=$(awk -F'= *' '$1=="pkgver"{print $2; exit}' "pkgs/${pkg}/PKGBUILD")
110+
111+
# Commit package updates and README
112+
git add README.md README.zh.md docs/readme.en.md 2>/dev/null || true
113+
114+
git commit -m "ci: update ${pkg} to ${new_version}
115+
116+
Automated upstream version detection via monitor-upstream workflow.
117+
118+
Co-Authored-By: github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
119+
done
120+
121+
# Pull before push to avoid conflicts
122+
git pull --rebase origin main || {
123+
echo "Failed to rebase, attempting merge" >&2
124+
git rebase --abort
125+
git pull --no-rebase origin main
126+
}
127+
128+
git push origin main
129+
130+
echo "Successfully committed updates for: ${updated_packages[*]}"
131+
132+
- name: Upload logs
133+
if: always()
134+
uses: actions/upload-artifact@v4
135+
with:
136+
name: monitor-logs-${{ github.run_id }}
137+
path: |
138+
*.log
139+
retention-days: 30
140+
if-no-files-found: ignore

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ pkgs/*/src/
99
*.log
1010
*.cache/
1111
*.tmp
12+
.workflow/

docs/guidelines.en.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,44 @@ Adopt Conventional Commits (`feat:`, `fix:`, `ci:`). Include upstream version bu
2323

2424
## Security & Configuration Tips
2525
Store AUR SSH keys and tokens inside repository secrets (e.g., `AUR_SSH_KEY`, `AUR_GIT_URL`) and rotate them quarterly. Never print secrets in scripts—use environment files or GitHub Actions secrets. Document any new credentials in `docs/secrets.md`, including rotation steps, so maintainers can audit quickly.
26+
27+
## CI/CD Automation
28+
GitHub Actions workflows automate upstream monitoring, package building, and AUR publishing. Two workflows handle the complete automation pipeline.
29+
30+
### Workflows Overview
31+
- **Monitor Upstream** (`monitor-upstream.yml`): Scheduled daily (00:00 UTC) to detect new releases via `scripts/update-package.sh`. Regenerates README with updated versions via `scripts/build-readme.sh`. Commits all changes to trigger build workflow.
32+
- **Build and Publish** (`build-and-publish.yml`): Triggered by PKGBUILD/SRCINFO changes. Uses mature GitHub Actions for all operations:
33+
- Build/validation: [heyhusen/archlinux-package-action](https://github.com/heyhusen/archlinux-package-action) v2
34+
- AUR publishing: [KSXGitHub/github-actions-deploy-aur](https://github.com/KSXGitHub/github-actions-deploy-aur) v2.7.0
35+
36+
### GitHub Secrets Configuration
37+
Configure secrets in repository Settings → Secrets and variables → Actions:
38+
39+
**Required**:
40+
- `AUR_SSH_KEY`: Private SSH key for AUR authentication. Generate with `ssh-keygen -t rsa -b 4096 -C "aur@github-actions"`, then add the public key to your AUR account SSH settings at https://aur.archlinux.org/account/.
41+
42+
### Manual Workflow Triggers
43+
Both workflows support manual execution via workflow_dispatch:
44+
45+
**Monitor Upstream**:
46+
- Navigate to Actions → Monitor Upstream Releases → Run workflow
47+
- Parameters: `package` (specific package or empty for all), `force` (force update checkbox)
48+
49+
**Build and Publish**:
50+
- Navigate to Actions → Build and Publish to AUR → Run workflow
51+
- Parameters: `package` (required), `skip_publish` (dry-run checkbox)
52+
53+
### Build Environment
54+
Workflows run on `ubuntu-latest` runners and use containerized Arch Linux environments via GitHub Actions. All package operations (makepkg, namcap, AUR publishing) are handled by mature, community-maintained actions with automatic environment setup.
55+
56+
### Troubleshooting Workflows
57+
- **Build failures**: Check Actions logs for makepkg/namcap output. The archlinux-package-action automatically runs `makepkg -s --noconfirm` and validates with namcap. Test locally with `makepkg --syncdeps --cleanbuild`.
58+
- **SSH authentication errors**: Verify `AUR_SSH_KEY` secret configured correctly (must be RSA private key), public key added to AUR account. Test locally: `ssh -T aur@aur.archlinux.org`.
59+
- **AUR publish errors**: Check publish step logs for details. The github-actions-deploy-aur action automatically handles git operations, SSH setup, and file copying. Ensure PKGBUILD and .SRCINFO are valid.
60+
- **No updates detected**: Check `scripts/update-package.sh` output, verify upstream.sh hooks working. Test manually: `./scripts/update-package.sh <package>`.
61+
- **namcap validation fails**: Build action runs namcap on both PKGBUILD and built packages. Review logs, fix issues locally before pushing.
62+
63+
### Artifact Retention
64+
- Build packages (`*.pkg.tar.zst`): 90 days retention
65+
- Build logs and source directory: 30 days retention
66+
- Download from Actions → Workflow run → Artifacts section

docs/guidelines.zh.md

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[English Version](guidelines.en.md)
44

55
## 项目结构与模块组织
6-
本仓库用于自动化维护 AUR 软件包:负责检测上游新版本、重新构建并推送到 AUR。GitHub Actions 工作流位于 `.github/workflows/``monitor-upstream.yml` 用于定时检测,`release.yml` 负责发布。通用脚本集中在 `scripts/`,编排逻辑由 `update-package.sh` 负责,后续的共享函数会放在 `scripts/lib/`。每个软件包在 `pkgs/<包名>/` 下维护自己的 `PKGBUILD``.SRCINFO` 以及对应的 `upstream.sh`
6+
本仓库用于自动化维护 AUR 软件包:负责检测上游新版本、重新构建并推送到 AUR。GitHub Actions 工作流位于 `.github/workflows/``monitor-upstream.yml` 用于定时检测,`build-and-publish.yml` 负责构建和发布。通用脚本集中在 `scripts/`,编排逻辑由 `update-package.sh` 负责,后续的共享函数会放在 `scripts/lib/`。每个软件包在 `pkgs/<包名>/` 下维护自己的 `PKGBUILD``.SRCINFO` 以及对应的 `upstream.sh`
77

88
## 构建与测试命令
99
如需本地操作,可执行 `source scripts/env.sh`(若存在)并使用 `./scripts/<脚本名>.sh`。常见的本地检查包括:
@@ -22,4 +22,45 @@ Shell 脚本统一使用 Bash,开头加上 `set -euo pipefail`,并采用两
2222
提交信息遵循 Conventional Commits(如 `feat:``fix:``ci:`),并在标题中注明上游版本号(示例:`fix: bump kdenlive to 25.08.2`)。PR 必须同时更新 `PKGBUILD``.SRCINFO`,附上 CI 日志,并关联上游发布或问题链接。确保 GitHub Actions 全部通过后再请求评审。
2323

2424
## 安全与配置提示
25-
AUR 的 SSH 密钥和令牌应存储在仓库的 Secrets(如 `AUR_SSH_KEY``AUR_GIT_URL`)中,并建议按季度轮换。脚本中禁止直接输出敏感信息,可通过环境文件或 Actions Secrets 注入。若新增凭据,请记录在 `docs/secrets.md`,包含轮换流程,方便维护人员审计。
25+
AUR 的 SSH 密钥和令牌应存储在仓库的 Secrets(如 `AUR_SSH_KEY`)中,并建议按季度轮换。脚本中禁止直接输出敏感信息,可通过环境文件或 Actions Secrets 注入。若新增凭据,请记录在 `docs/secrets.md`,包含轮换流程,方便维护人员审计。
26+
27+
## CI/CD 自动化
28+
GitHub Actions 工作流自动化了上游监控、软件包构建和 AUR 发布。两个工作流处理完整的自动化流程。
29+
30+
### 工作流概述
31+
- **Monitor Upstream**`monitor-upstream.yml`):每日定时(UTC 00:00)通过 `scripts/update-package.sh` 检测新版本。通过 `scripts/build-readme.sh` 重新生成 README 并更新版本信息。提交所有更改以触发构建工作流。
32+
- **Build and Publish**`build-and-publish.yml`):由 PKGBUILD/SRCINFO 变更触发。使用成熟的 GitHub Actions 完成所有操作:
33+
- 构建/验证:[heyhusen/archlinux-package-action](https://github.com/heyhusen/archlinux-package-action) v2
34+
- AUR 发布:[KSXGitHub/github-actions-deploy-aur](https://github.com/KSXGitHub/github-actions-deploy-aur) v2.7.0
35+
36+
### GitHub Secrets 配置
37+
在仓库的 Settings → Secrets and variables → Actions 中配置:
38+
39+
**必需**
40+
- `AUR_SSH_KEY`:用于 AUR 身份验证的私钥。使用 `ssh-keygen -t rsa -b 4096 -C "aur@github-actions"` 生成,然后在 https://aur.archlinux.org/account/ 添加公钥。
41+
42+
### 手动触发工作流
43+
两个工作流都支持通过 workflow_dispatch 手动执行:
44+
45+
**Monitor Upstream**
46+
- 导航到 Actions → Monitor Upstream Releases → Run workflow
47+
- 参数:`package`(指定包或留空检查所有包)、`force`(强制更新复选框)
48+
49+
**Build and Publish**
50+
- 导航到 Actions → Build and Publish to AUR → Run workflow
51+
- 参数:`package`(必需)、`skip_publish`(干运行复选框)
52+
53+
### 构建环境
54+
工作流运行在 `ubuntu-latest` runner 上,通过 GitHub Actions 使用容器化的 Arch Linux 环境。所有软件包操作(makepkg、namcap、AUR 发布)由成熟的社区维护 actions 处理,自动完成环境设置。
55+
56+
### 工作流故障排除
57+
- **构建失败**:查看 Actions 日志中的 makepkg/namcap 输出。archlinux-package-action 自动运行 `makepkg -s --noconfirm` 并使用 namcap 验证。本地测试:`makepkg --syncdeps --cleanbuild`
58+
- **SSH 认证错误**:验证 `AUR_SSH_KEY` secret 配置正确(必须是 RSA 私钥),公钥已添加到 AUR 账户。本地测试:`ssh -T aur@aur.archlinux.org`
59+
- **AUR 发布错误**:检查发布步骤日志。github-actions-deploy-aur action 自动处理 git 操作、SSH 设置和文件复制。确保 PKGBUILD 和 .SRCINFO 有效。
60+
- **未检测到更新**:检查 `scripts/update-package.sh` 输出,验证 upstream.sh 钩子是否正常工作。手动测试:`./scripts/update-package.sh <包名>`
61+
- **namcap 验证失败**:构建 action 会在 PKGBUILD 和构建的包上运行 namcap。查看日志,在推送前本地修复问题。
62+
63+
### 产物保留
64+
- 构建包(`*.pkg.tar.zst`):90 天保留期
65+
- 构建日志和源码目录:30 天保留期
66+
- 从 Actions → Workflow run → Artifacts 部分下载

docs/packaging.zh.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
- `pkgs/<包名>/.SRCINFO`:通过 `makepkg --printsrcinfo` 重新生成。
88
- `pkgs/<包名>/upstream.sh`:定义包的更新钩子,实现自动化。
99
- `scripts/update-package.sh`:通用框架脚本,调用各包钩子。
10+
- `.github/workflows/monitor-upstream.yml`:定时检测上游版本更新。
11+
- `.github/workflows/build-and-publish.yml`:自动构建并发布到 AUR。
1012

1113
补丁或启动脚本请放在对应包目录下。AppImage 的桌面集成(包装脚本、图标、`.desktop` 文件)应在 `package()` 中生成,不要直接提交二进制资产。
1214

0 commit comments

Comments
 (0)