Build Rootfs #85
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build Rootfs | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| target: | |
| description: "Build target" | |
| required: true | |
| type: choice | |
| options: | |
| - rootfs-chromium | |
| - rootfs-qwenpaw | |
| - rootfs-hermes | |
| - rootfs-openclaw | |
| default: rootfs-chromium | |
| arch: | |
| description: "Architectures to build" | |
| required: true | |
| type: choice | |
| options: | |
| - both | |
| - x86_64 | |
| - arm64 | |
| default: both | |
| upload_to_oss: | |
| description: "Upload qcow2 to OSS after build" | |
| required: true | |
| type: boolean | |
| default: true | |
| update_images_json: | |
| description: "Update images.json after build" | |
| required: true | |
| type: boolean | |
| default: true | |
| jobs: | |
| build-x86_64: | |
| if: inputs.arch == 'both' || inputs.arch == 'x86_64' | |
| runs-on: ubuntu-latest | |
| name: "${{ inputs.target }} (x86_64)" | |
| timeout-minutes: 120 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Show disk space | |
| run: df -h | |
| - name: Build | |
| run: ./scripts/docker/build.sh x86_64 ${{ inputs.target }} | |
| - name: Find qcow2 output | |
| id: find | |
| run: | | |
| QCOW2=$(find build/share/ -name '*.qcow2' -print -quit 2>/dev/null) | |
| if [ -z "$QCOW2" ]; then | |
| echo "No qcow2 file found in build/share/" | |
| exit 1 | |
| fi | |
| echo "qcow2_path=$QCOW2" >> "$GITHUB_OUTPUT" | |
| echo "qcow2_name=$(basename "$QCOW2")" >> "$GITHUB_OUTPUT" | |
| echo "qcow2_size=$(stat -c%s "$QCOW2")" >> "$GITHUB_OUTPUT" | |
| SHA256=$(sha256sum "$QCOW2" | cut -d' ' -f1) | |
| echo "qcow2_sha256=$SHA256" >> "$GITHUB_OUTPUT" | |
| echo "Found: $QCOW2 ($(du -h "$QCOW2" | cut -f1))" | |
| - name: Upload to OSS | |
| if: inputs.upload_to_oss | |
| env: | |
| OSS_REGION: ${{ secrets.OSS_REGION }} | |
| OSS_ACCESS_KEY_ID: ${{ secrets.OSS_ACCESS_KEY_ID }} | |
| OSS_ACCESS_KEY_SECRET: ${{ secrets.OSS_ACCESS_KEY_SECRET }} | |
| OSS_BUCKET_NAME: ${{ secrets.OSS_BUCKET_NAME }} | |
| OSS_PUBLIC_URL: https://files.xiaozhi.me | |
| OSS_TENBOX_IMAGES_DIR: tenbox/images | |
| run: | | |
| pip install oss2 alibabacloud_cdn20180510 | |
| python3 scripts/ci/upload_to_oss.py \ | |
| "${{ steps.find.outputs.qcow2_path }}" \ | |
| "${{ inputs.target }}" \ | |
| x86_64 | |
| - name: Save build metadata | |
| if: inputs.update_images_json | |
| run: | | |
| mkdir -p /tmp/meta | |
| cat > /tmp/meta/x86_64.json <<EOF | |
| { | |
| "arch": "x86_64", | |
| "filename": "${{ steps.find.outputs.qcow2_name }}", | |
| "sha256": "${{ steps.find.outputs.qcow2_sha256 }}", | |
| "size": ${{ steps.find.outputs.qcow2_size }} | |
| } | |
| EOF | |
| - name: Upload build metadata | |
| if: inputs.update_images_json | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: meta-x86_64 | |
| path: /tmp/meta/x86_64.json | |
| retention-days: 1 | |
| build-arm64: | |
| if: inputs.arch == 'both' || inputs.arch == 'arm64' | |
| runs-on: ubuntu-24.04-arm | |
| name: "${{ inputs.target }} (arm64)" | |
| timeout-minutes: 120 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Show disk space | |
| run: df -h | |
| - name: Build | |
| run: ./scripts/docker/build.sh arm64 ${{ inputs.target }} | |
| - name: Find qcow2 output | |
| id: find | |
| run: | | |
| QCOW2=$(find build/share/ -name '*.qcow2' -print -quit 2>/dev/null) | |
| if [ -z "$QCOW2" ]; then | |
| echo "No qcow2 file found in build/share/" | |
| exit 1 | |
| fi | |
| echo "qcow2_path=$QCOW2" >> "$GITHUB_OUTPUT" | |
| echo "qcow2_name=$(basename "$QCOW2")" >> "$GITHUB_OUTPUT" | |
| echo "qcow2_size=$(stat -c%s "$QCOW2")" >> "$GITHUB_OUTPUT" | |
| SHA256=$(sha256sum "$QCOW2" | cut -d' ' -f1) | |
| echo "qcow2_sha256=$SHA256" >> "$GITHUB_OUTPUT" | |
| echo "Found: $QCOW2 ($(du -h "$QCOW2" | cut -f1))" | |
| - name: Upload to OSS | |
| if: inputs.upload_to_oss | |
| env: | |
| OSS_REGION: ${{ secrets.OSS_REGION }} | |
| OSS_ACCESS_KEY_ID: ${{ secrets.OSS_ACCESS_KEY_ID }} | |
| OSS_ACCESS_KEY_SECRET: ${{ secrets.OSS_ACCESS_KEY_SECRET }} | |
| OSS_BUCKET_NAME: ${{ secrets.OSS_BUCKET_NAME }} | |
| OSS_PUBLIC_URL: https://files.xiaozhi.me | |
| OSS_TENBOX_IMAGES_DIR: tenbox/images | |
| run: | | |
| pip install oss2 alibabacloud_cdn20180510 | |
| python3 scripts/ci/upload_to_oss.py \ | |
| "${{ steps.find.outputs.qcow2_path }}" \ | |
| "${{ inputs.target }}" \ | |
| arm64 | |
| - name: Save build metadata | |
| if: inputs.update_images_json | |
| run: | | |
| mkdir -p /tmp/meta | |
| cat > /tmp/meta/arm64.json <<EOF | |
| { | |
| "arch": "arm64", | |
| "filename": "${{ steps.find.outputs.qcow2_name }}", | |
| "sha256": "${{ steps.find.outputs.qcow2_sha256 }}", | |
| "size": ${{ steps.find.outputs.qcow2_size }} | |
| } | |
| EOF | |
| - name: Upload build metadata | |
| if: inputs.update_images_json | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: meta-arm64 | |
| path: /tmp/meta/arm64.json | |
| retention-days: 1 | |
| update-images-json: | |
| if: >- | |
| always() | |
| && inputs.update_images_json | |
| && (needs.build-x86_64.result == 'success' || needs.build-arm64.result == 'success') | |
| needs: [build-x86_64, build-arm64] | |
| runs-on: ubuntu-latest | |
| name: "Update images.json" | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download all metadata | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: meta-* | |
| path: /tmp/meta | |
| merge-multiple: true | |
| - name: List metadata | |
| run: ls -la /tmp/meta/ && cat /tmp/meta/*.json | |
| # Default: sha256 left empty so clients skip verification (OSS can update before PR merges). | |
| # Add --enable-sha256 to the script call if you want checksums in the manifest. | |
| - name: Update images.json | |
| id: update | |
| env: | |
| OSS_PUBLIC_URL: https://files.xiaozhi.me | |
| OSS_TENBOX_IMAGES_DIR: tenbox/images | |
| run: | | |
| python3 scripts/ci/update_images_json.py \ | |
| --target "${{ inputs.target }}" \ | |
| --meta-dir /tmp/meta | |
| - name: Create branch, commit and open PR | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add website/public/api/images.json | |
| git diff --cached --quiet && echo "No changes to commit" && exit 0 | |
| VERSION="${{ steps.update.outputs.version }}" | |
| TARGET="${{ inputs.target }}" | |
| NAME="${TARGET#rootfs-}" | |
| if [ -n "$VERSION" ]; then | |
| MSG="ci: update ${NAME} to ${VERSION}" | |
| else | |
| MSG="ci: update ${NAME}" | |
| fi | |
| BRANCH="ci/update-${NAME}-$(date +%Y%m%d-%H%M%S)" | |
| git checkout -b "$BRANCH" | |
| git commit -m "$MSG" | |
| git push -u origin "$BRANCH" | |
| gh pr create --title "$MSG" --body "Auto-generated by Build Rootfs workflow." --base main |