Create Release #54
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: Create Release | |
| permissions: | |
| contents: write | |
| on: | |
| schedule: | |
| # Run every Monday at 2am UTC | |
| - cron: "0 2 * * 1" | |
| workflow_dispatch: | |
| inputs: | |
| board: | |
| description: "Target board to build (or all)" | |
| required: true | |
| default: "all" | |
| type: choice | |
| options: | |
| - all | |
| - rpi | |
| - nanopi-r3s | |
| - nanopi-zero2 | |
| - nanopi-r76s | |
| draft: | |
| description: "Create as draft release for testing" | |
| required: false | |
| default: true | |
| type: boolean | |
| jobs: | |
| prepare: | |
| runs-on: depot-ubuntu-24.04-arm | |
| outputs: | |
| matrix: ${{ steps.set-matrix.outputs.matrix }} | |
| release_name: ${{ steps.release-name.outputs.name }} | |
| release_tag: ${{ steps.release-name.outputs.tag }} | |
| release_id: ${{ steps.create-release.outputs.id }} | |
| release_upload_url: ${{ steps.create-release.outputs.upload_url }} | |
| is_draft: ${{ steps.set-draft.outputs.is_draft }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Compute matrix | |
| id: set-matrix | |
| run: | | |
| # For scheduled runs, build all boards | |
| if [[ "${{ github.event_name }}" == "schedule" ]]; then | |
| MATRIX='["rpi","nanopi-r3s","nanopi-zero2","nanopi-r76s"]' | |
| else | |
| choice='${{ inputs.board }}' | |
| case "$choice" in | |
| all) MATRIX='["rpi","nanopi-r3s","nanopi-zero2","nanopi-r76s"]' ;; | |
| rpi) MATRIX='["rpi"]' ;; | |
| nanopi-r3s) MATRIX='["nanopi-r3s"]' ;; | |
| nanopi-zero2) MATRIX='["nanopi-zero2"]' ;; | |
| nanopi-r76s) MATRIX='["nanopi-r76s"]' ;; | |
| *) echo "Unknown board: $choice" >&2; exit 1 ;; | |
| esac | |
| fi | |
| echo "matrix=$MATRIX" >> $GITHUB_OUTPUT | |
| - name: Generate release name | |
| id: release-name | |
| run: | | |
| # Generate base name from current month and year (YYYY-MM format) | |
| base_name=$(date '+%Y-%m') | |
| # Get the latest release tag matching the base pattern | |
| latest_tag=$(gh release list --json tagName --jq '.[].tagName' | grep "^v${base_name}" | head -n1 || echo "") | |
| # Extract increment number from latest tag, or start at 1 | |
| if [[ -n "$latest_tag" && $latest_tag =~ ^v${base_name}\.([0-9]+)$ ]]; then | |
| increment=$((BASH_REMATCH[1] + 1)) | |
| else | |
| increment=1 | |
| fi | |
| # Always use .x notation | |
| release_name="${base_name}.${increment}" | |
| release_tag="v${base_name}.${increment}" | |
| echo "name=$release_name" >> $GITHUB_OUTPUT | |
| echo "tag=$release_tag" >> $GITHUB_OUTPUT | |
| echo "Release will be named: $release_name (tag: $release_tag)" | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Determine draft mode | |
| id: set-draft | |
| run: | | |
| if [[ "${{ github.event_name }}" == "schedule" ]]; then | |
| echo "is_draft=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "is_draft=${{ inputs.draft }}" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Generate release notes | |
| run: | | |
| echo "Latest evcc stable version on Armbian bookworm." > release_notes.md | |
| - name: Create Release | |
| id: create-release | |
| uses: actions/create-release@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| tag_name: ${{ steps.release-name.outputs.tag }} | |
| release_name: evcc Images ${{ steps.release-name.outputs.name }} | |
| body_path: release_notes.md | |
| draft: true | |
| prerelease: false | |
| build: | |
| needs: prepare | |
| runs-on: depot-ubuntu-24.04-arm-32 | |
| timeout-minutes: 360 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| board: ${{ fromJSON(needs.prepare.outputs.matrix) }} | |
| name: Build ${{ matrix.board }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Prepare Docker and workspace | |
| run: | | |
| mkdir -p dist logs | |
| sudo apt-get update | |
| sudo apt-get install -y qemu-user-static binfmt-support xz-utils zip | |
| - name: Ensure loop devices | |
| run: | | |
| sudo modprobe loop | |
| sudo losetup -D | |
| # Create loop device nodes if missing | |
| for i in $(seq 0 15); do | |
| [ -e /dev/loop$i ] || sudo mknod /dev/loop$i b 7 $i | |
| done | |
| ls -la /dev/loop* | |
| - name: Build image | |
| run: | | |
| set -euo pipefail | |
| chmod +x ./scripts/build-armbian.sh | |
| echo "::group::Building for ${{ matrix.board }}" | |
| bash ./scripts/build-armbian.sh \ | |
| --board "${{ matrix.board }}" \ | |
| --release-name "${{ needs.prepare.outputs.release_name }}" | |
| echo "::endgroup::" | |
| - name: Compress .img file | |
| run: | | |
| IMG_FILE=$(find dist -name "*.img" -type f) | |
| [ -z "$IMG_FILE" ] && { echo "No .img file found"; exit 1; } | |
| cd "$(dirname "$IMG_FILE")" | |
| zip -9 "$(basename "$IMG_FILE").zip" "$(basename "$IMG_FILE")" | |
| rm "$(basename "$IMG_FILE")" | |
| - name: Find built files | |
| id: find-files | |
| run: | | |
| echo "img_zip=$(find dist -name "*.img.zip" -type f)" >> $GITHUB_OUTPUT | |
| echo "sha_file=$(find dist -name "*.img.sha" -type f)" >> $GITHUB_OUTPUT | |
| echo "txt_file=$(find dist -name "*.img.txt" -type f)" >> $GITHUB_OUTPUT | |
| - name: Upload compressed image to release | |
| uses: actions/upload-release-asset@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| upload_url: ${{ needs.prepare.outputs.release_upload_url }} | |
| asset_path: ${{ steps.find-files.outputs.img_zip }} | |
| asset_name: evcc_${{ needs.prepare.outputs.release_name }}_${{ matrix.board }}.img.zip | |
| asset_content_type: application/zip | |
| - name: Upload SHA file to release | |
| uses: actions/upload-release-asset@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| upload_url: ${{ needs.prepare.outputs.release_upload_url }} | |
| asset_path: ${{ steps.find-files.outputs.sha_file }} | |
| asset_name: evcc_${{ needs.prepare.outputs.release_name }}_${{ matrix.board }}.img.sha | |
| asset_content_type: text/plain | |
| - name: Upload TXT file to release | |
| uses: actions/upload-release-asset@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| upload_url: ${{ needs.prepare.outputs.release_upload_url }} | |
| asset_path: ${{ steps.find-files.outputs.txt_file }} | |
| asset_name: evcc_${{ needs.prepare.outputs.release_name }}_${{ matrix.board }}.img.txt | |
| asset_content_type: text/plain | |
| finalize: | |
| needs: [prepare, build] | |
| runs-on: depot-ubuntu-24.04-arm | |
| if: success() && needs.prepare.outputs.is_draft != 'true' | |
| steps: | |
| - name: Publish release | |
| run: | | |
| gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" --draft=false | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAG: ${{ needs.prepare.outputs.release_tag }} | |
| cleanup: | |
| needs: [prepare, build] | |
| runs-on: depot-ubuntu-24.04-arm | |
| if: failure() && needs.prepare.outputs.is_draft != 'true' | |
| steps: | |
| - name: Delete failed release | |
| run: | | |
| gh release delete "$TAG" --repo "$GITHUB_REPOSITORY" --yes --cleanup-tag | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAG: ${{ needs.prepare.outputs.release_tag }} |