name: App Version CI/CD on: pull_request: types: - opened - synchronize - reopened env: GH_TOKEN: ${{ github.token }} PR_NUMBER: ${{ github.event.pull_request.number }} jobs: get-latest-commit-author: name: Get Latest Commit Author runs-on: ubuntu-latest outputs: latest_commit_author: ${{ steps.latest-commit-author.outputs.latest_commit_author }} steps: - name: Get latest commit author id: latest-commit-author run: | resp=$(gh api \ -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ /repos/${{ github.repository}}/commits/${{ github.event.pull_request.head.ref }}) author=$(echo "$resp" | jq -r '.author.login // empty') echo "the Author of Latest Commit on Head Branch: $author" echo "latest_commit_author=$author" >> $GITHUB_OUTPUT update-app-version: name: Update App Version needs: get-latest-commit-author if: | github.actor == 'renovate[bot]' && needs.get-latest-commit-author.outputs.latest_commit_author != github.repository_owner && startsWith(github.head_ref, 'renovate/') runs-on: ubuntu-latest permissions: contents: write statuses: write steps: - name: Checkout uses: actions/checkout@v6.0.2 with: fetch-depth: 0 ref: ${{ github.head_ref }} - uses: actions/setup-python@main with: python-version: 3.x pip-install: PyYAML - name: Configure repo run: | git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" - name: Get list of updated files by the last commit in this branch separated by space id: updated-files run: | # 当触发工作流的事件为 pull_request 时,github.sha 值为 github.ref 分支上的最后一次合并提交 files=$(git diff-tree --no-commit-id --name-only -r ${{ github.event.pull_request.head.sha }} | tr '\n' ' ') if [ -z "$files" ]; then echo "❌ 错误:没有检测到文件变更" echo "github.sha = ${{ github.sha }}" echo "github.event.pull_request.head.sha = ${{ github.event.pull_request.head.sha }}" echo "当前分支最新的提交SHA: $(git rev-parse HEAD)" echo "💡 最近三次提交:" echo " $(git log -3)" exit 1 else echo "files=$files" >> $GITHUB_OUTPUT fi - name: Run renovate-app-version.py on updated files run: | IFS=' ' read -ra files <<< "${{ steps.updated-files.outputs.files }}" for file in "${files[@]}"; do if [[ $file == *"docker-compose.yml"* ]]; then app_name=$(echo $file | cut -d'/' -f 2) old_version=$(echo $file | cut -d'/' -f 3) python3 .github/workflows/renovate-app-version.py $app_name $old_version fi if [[ $file == *"/scripts/"*.sh ]]; then app_name=$(echo $file | cut -d'/' -f 2) old_version=$(echo $file | cut -d'/' -f 3) new_version=$(grep -P -o '[\S]+=[\S]+:\K[\S]+' $file | head -1) mv apps/$app_name/$old_version apps/$app_name/$new_version echo $new_version > apps/$app_name/${old_version}.version fi done - name: Commit & Push Changes run: | IFS=' ' read -ra files <<< "${{ steps.updated-files.outputs.files }}" commits_counter=0 for file in "${files[@]}"; do if [[ $file == *"docker-compose.yml"* || $file == *"/scripts/"*.sh ]]; then app_name=$(echo $file | cut -d'/' -f 2) old_version=$(echo $file | cut -d'/' -f 3) if [ -f "apps/$app_name/${old_version}.version" ]; then new_version=$(cat "apps/$app_name/${old_version}.version") rm -f "apps/$app_name/${old_version}.version" echo "处理: $app_name - $old_version → $new_version" if [ ! -d "apps/$app_name/$old_version" ]; then echo "✅ 旧目录不存在: apps/$app_name/$old_version" fi if [ -d "apps/$app_name/$new_version" ]; then echo "✅ 新目录存在: apps/$app_name/$new_version" else echo "⚠️ 新目录不存在: apps/$app_name/$new_version" exit 1 fi git reset git rm -r "apps/$app_name/$old_version" git add "apps/$app_name/$new_version" if git diff --cached --quiet; then echo "⚠️ 没有检测到文件变更,跳过提交" else git commit --quiet -m "🔧 chore($app_name): update app version from $old_version to $new_version" --no-verify echo $(git show -s --format=%H) >> /tmp/commit-shas.txt commits_counter=$((commits_counter + 1)) echo "第 $commits_counter 个提交" echo "✅ 已提交: apps/$app_name/{$old_version → $new_version}" fi else echo "处理: $app_name - $old_version" echo "⚠️ 没有找到版本标记文件: apps/$app_name/${old_version}.version" fi fi done if [ $commits_counter -gt 0 ]; then echo "推送 $commits_counter 个提交到远程仓库..." git push while IFS= read -r sha; do if [[ -n "$sha" ]]; then gh api --silent --method POST -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ /repos/${{ github.repository }}/statuses/$sha \ -f 'state=success' \ -f 'target_url=https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' \ -f 'description=CI/CD' \ -f 'context=${{ github.workflow}}' fi done < /tmp/commit-shas.txt else echo "没有提交需要推送" fi check-labels: name: Check labels if: | github.actor == 'renovate[bot]' runs-on: ubuntu-latest outputs: enable: ${{ steps.check-labels.outputs.enable }} permissions: contents: write pull-requests: write steps: - name: Checkout code uses: actions/checkout@v6 - name: Check for major label id: check-labels run: | pr_labels='${{ join(github.event.pull_request.labels.*.name, ',') }}' if [[ $pr_labels =~ "major" ]]; then echo "❌ PR has major label" echo "enable=false" >> $GITHUB_OUTPUT else echo "✅ PR does not have major label" echo "enable=true" >> $GITHUB_OUTPUT fi # - name: Add reviewer and comment for major PR # if: steps.check-labels.outputs.enable == 'false' # run: | # gh pr edit $PR_NUMBER --add-reviewer ${{ github.repository_owner }} # gh pr edit $PR_NUMBER --add-assignee ${{ github.repository_owner }} - name: remove labels run: | pr_labels='${{ join(github.event.pull_request.labels.*.name, ',') }}' IFS=',' read -ra labels_array <<< "$pr_labels" for label in "${labels_array[@]}"; do echo "Removing label: $label" gh pr edit $PR_NUMBER --remove-label="$label" done merge-prs: name: Auto Merge the PR runs-on: ubuntu-latest needs: - update-app-version - check-labels if: | needs.check-labels.outputs.enable == 'true' && (needs.update-app-version.result == 'success' || needs.update-app-version.result == 'skipped') permissions: contents: write pull-requests: write steps: - name: Checkout repository uses: actions/checkout@v6 with: ref: ${{ github.base_ref }} - name: Merge PR run: | max_attempts=5 for attempt in $(seq 1 $max_attempts); do if gh pr merge $PR_NUMBER --squash --delete-branch --body ""; then echo "✅ Merge PR #$PR_NUMBER Success" exit 0 else echo "⚠️ Merge PR #$PR_NUMBER Failed ($attempt / $max_attempts)" sleep 5 fi done