Skip to content

Create Release

Create Release #54

Workflow file for this run

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 }}