Release Build #103
This file contains 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
# RaspberryMatic Release build | |
# yamllint disable rule:truthy | |
--- | |
name: Release Build | |
on: | |
workflow_dispatch: | |
inputs: | |
release_date: | |
description: 'Release date override (YYYYMMDD)' | |
required: true | |
default: "YYYYMMDD" | |
skip_build: | |
description: 'Skip build (for testing workflow)?' | |
required: true | |
default: "true" | |
# default read-only permission | |
permissions: | |
contents: read | |
jobs: | |
release_draft: | |
permissions: | |
contents: write # ncipollo/release-action | |
name: Release draft | |
runs-on: ubuntu-22.04 | |
outputs: | |
upload_url: ${{ steps.release_drafter.outputs.upload_url }} | |
occu_version: ${{ steps.env.outputs.occu_version }} | |
version: ${{ steps.env.outputs.version }} | |
date: ${{ steps.env.outputs.date }} | |
tag: ${{ steps.env.outputs.tag }} | |
steps: | |
- name: Checkout Code | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Setup Environment | |
id: env | |
shell: bash | |
run: | | |
if [[ "${{ github.event.inputs.release_date }}" == "YYYYMMDD" ]]; then | |
BUILD_DATE=$(date +%Y%m%d) | |
else | |
BUILD_DATE=${{ github.event.inputs.release_date }} | |
fi | |
OCCU_VERSION=$(grep 'OCCU_VERSION =' buildroot-external/package/occu/occu.mk | cut -d' ' -f3 | cut -d'-' -f1) | |
echo "occu_version=${OCCU_VERSION}" >> $GITHUB_OUTPUT | |
echo "version=${OCCU_VERSION}.${BUILD_DATE}" >> $GITHUB_OUTPUT | |
echo "date=${BUILD_DATE}" >> $GITHUB_OUTPUT | |
if [[ "${{ github.event.inputs.skip_build }}" == "true" ]]; then | |
echo "tag=${OCCU_VERSION}.${BUILD_DATE}-draft" >> $GITHUB_OUTPUT | |
else | |
echo "tag=${OCCU_VERSION}.${BUILD_DATE}" >> $GITHUB_OUTPUT | |
fi | |
- name: Get previous tag | |
id: previoustag | |
uses: WyriHaximus/github-action-get-previous-tag@v1.3 | |
- name: Generate changelog | |
id: changelog | |
uses: metcalfc/changelog-generator@v4.2.0 | |
with: | |
myToken: ${{ secrets.GITHUB_TOKEN }} | |
- name: Generate release notes | |
shell: bash | |
run: | | |
FILTER="(snapshot bump \[|Merge branch '|Update .*\.md$|Bump .* from .* to .*)" | |
export CHANGELOG="$(cat <<'EOF' | egrep -v "${FILTER}" | |
${{ steps.changelog.outputs.changelog }} | |
EOF | |
)" | |
export VERSION=${{ steps.env.outputs.version }} | |
export PREVIOUS_TAG=${{ steps.previoustag.outputs.tag }} | |
envsubst <.github/release-template.md >/tmp/release-template.md | |
- name: Create release draft | |
id: release_drafter | |
uses: ncipollo/release-action@v1.13.0 | |
with: | |
tag: ${{ steps.env.outputs.tag }} | |
name: 'RaspberryMatic ${{ steps.env.outputs.version }}' | |
bodyFile: /tmp/release-template.md | |
draft: true | |
prerelease: false | |
allowUpdates: true | |
token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Upload release-template.md artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
path: /tmp/release-template.md | |
name: release-template.md | |
build: | |
permissions: | |
contents: write # shogo82148/actions-upload-release-asset | |
name: Release build [${{ matrix.platform }}] | |
if: github.repository == 'jens-maus/RaspberryMatic' | |
runs-on: self-hosted | |
timeout-minutes: 480 | |
needs: release_draft | |
outputs: | |
build_datetime: ${{ steps.env.outputs.build_datetime }} | |
strategy: | |
fail-fast: false | |
matrix: | |
platform: [rpi0, rpi2, rpi3, rpi4, rpi5, tinkerboard, odroid-c2, odroid-c4, odroid-n2, intelnuc, ova, oci_amd64, oci_arm64, oci_arm, generic-aarch64] | |
steps: | |
- name: Checkout Code | |
uses: actions/checkout@v4 | |
- name: Install Dependencies | |
run: | | |
if ! dpkg-query -l wget bc cpio rsync zip python3 file >/dev/null 2>&1; then | |
apt update | |
apt install -y --no-install-recommends wget bc cpio rsync zip python3 file | |
fi | |
if ! getent group | grep -q ^builder:; then groupadd -g 48 builder; fi | |
if ! getent passwd | grep -q ^builder:; then useradd -m -u 1003 -g 48 -G sudo builder; fi | |
if ! grep -q ^builder; then echo "builder ALL=(ALL:ALL) NOPASSWD: ALL" >>/etc/sudoers; fi | |
chown -R builder:builder /home/builder | |
- name: Setup Environment | |
id: env | |
run: | | |
JLEVEL=0 | |
if [[ -f /sys/fs/cgroup/cpu.max ]]; then # cgroups v2 | |
CPU_QUOTA=$(cut -d ' ' -f1 /sys/fs/cgroup/cpu.max) | |
if [[ "${CPU_QUOTA}" != "max" ]]; then | |
CPU_PERIOD=$(cut -d ' ' -f2 /sys/fs/cgroup/cpu.max) | |
JLEVEL=$((CPU_QUOTA / CPU_PERIOD + 1)) | |
fi | |
elif [[ -f /sys/fs/cgroup/cpu/cpu.cfs_quota_us ]]; then # cgroups v1 | |
CPU_QUOTA=$(cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us) | |
if [[ "${CPU_QUOTA}" != "-1" ]]; then | |
CPU_PERIOD=$(cat /sys/fs/cgroup/cpu/cpu.cfs_period_us) | |
JLEVEL=$((CPU_QUOTA / CPU_PERIOD + 1)) | |
fi | |
fi | |
echo "JLEVEL=${JLEVEL}" >> $GITHUB_ENV | |
echo "FAKE_BUILD=${{ github.event.inputs.skip_build }}" >> $GITHUB_ENV | |
echo "build_datetime=$(date +'%Y-%m-%d %H:%M:%S')" >> $GITHUB_OUTPUT | |
# - name: remote debug tmate session | |
# uses: mxschmitt/action-tmate@v1 | |
# if: matrix.platform == 'ova' | |
# major build step | |
- name: Build | |
timeout-minutes: 480 | |
run: | | |
sudo -H -E -u builder nice -n 19 make DATE=${{ needs.release_draft.outputs.date }} BR2_DL_DIR=/mnt/download BR2_CCACHE_DIR=/mnt/ccache/${{ matrix.platform }} BR2_JLEVEL=${{ env.JLEVEL }} clean raspmatic_${{ matrix.platform }}-release | |
# cleanup | |
- name: Cleanup | |
run: | | |
rm -f release/*.img* | |
make clean | |
####################### | |
# release uploads | |
- name: Upload release snapshot [rpi*, tinkerboard, odroid-*, intelnuc, ova, generic-*] | |
if: | | |
!startsWith(matrix.platform, 'oci_') | |
uses: shogo82148/actions-upload-release-asset@v1 | |
with: | |
upload_url: ${{ needs.release_draft.outputs.upload_url }} | |
asset_path: release/RaspberryMatic-${{ needs.release_draft.outputs.version }}-${{ matrix.platform }}.zip | |
asset_content_type: application/zip | |
- name: Upload build release checksum [rpi*, tinkerboard, intelnuc, ova, generic-*] | |
if: | | |
!startsWith(matrix.platform, 'oci_') | |
uses: shogo82148/actions-upload-release-asset@v1 | |
with: | |
upload_url: ${{ needs.release_draft.outputs.upload_url }} | |
asset_path: release/RaspberryMatic-${{ needs.release_draft.outputs.version }}-${{ matrix.platform }}.zip.sha256 | |
asset_content_type: text/plain | |
- name: Upload build release [ccu3] | |
if: | | |
matrix.platform == 'rpi3' | |
uses: shogo82148/actions-upload-release-asset@v1 | |
with: | |
upload_url: ${{ needs.release_draft.outputs.upload_url }} | |
asset_path: release/RaspberryMatic-${{ needs.release_draft.outputs.version }}-ccu3.tgz | |
asset_content_type: application/gzip | |
- name: Upload build release checksum [ccu3] | |
if: | | |
matrix.platform == 'rpi3' | |
uses: shogo82148/actions-upload-release-asset@v1 | |
with: | |
upload_url: ${{ needs.release_draft.outputs.upload_url }} | |
asset_path: release/RaspberryMatic-${{ needs.release_draft.outputs.version }}-ccu3.tgz.sha256 | |
asset_content_type: text/plain | |
- name: Upload build release [ova] | |
if: | | |
matrix.platform == 'ova' | |
uses: shogo82148/actions-upload-release-asset@v1 | |
with: | |
upload_url: ${{ needs.release_draft.outputs.upload_url }} | |
asset_path: release/RaspberryMatic-${{ needs.release_draft.outputs.version }}.ova | |
asset_content_type: application/gzip | |
- name: Upload build release checksum [ova] | |
if: | | |
matrix.platform == 'ova' | |
uses: shogo82148/actions-upload-release-asset@v1 | |
with: | |
upload_url: ${{ needs.release_draft.outputs.upload_url }} | |
asset_path: release/RaspberryMatic-${{ needs.release_draft.outputs.version }}.ova.sha256 | |
asset_content_type: text/plain | |
- name: Upload build release [oci] | |
if: | | |
startsWith(matrix.platform, 'oci_') | |
uses: shogo82148/actions-upload-release-asset@v1 | |
with: | |
upload_url: ${{ needs.release_draft.outputs.upload_url }} | |
asset_path: release/RaspberryMatic-${{ needs.release_draft.outputs.version }}-${{ matrix.platform }}.tgz | |
asset_content_type: application/gzip | |
- name: Upload build release checksum [oci] | |
if: | | |
startsWith(matrix.platform, 'oci_') | |
uses: shogo82148/actions-upload-release-asset@v1 | |
with: | |
upload_url: ${{ needs.release_draft.outputs.upload_url }} | |
asset_path: release/RaspberryMatic-${{ needs.release_draft.outputs.version }}-${{ matrix.platform }}.tgz.sha256 | |
asset_content_type: text/plain | |
######################## | |
# upload build artifacts | |
- name: Upload build artifact [oci] | |
if: | | |
startsWith(matrix.platform, 'oci_') | |
uses: actions/upload-artifact@v4 | |
with: | |
path: release/RaspberryMatic-${{ needs.release_draft.outputs.version }}-${{ matrix.platform }}.tgz* | |
name: RaspberryMatic-${{ needs.release_draft.outputs.version }}-${{ matrix.platform }}.tgz | |
continue-on-error: true | |
####################### | |
# manifest file artifact upload | |
- name: Upload manifest artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
path: release/RaspberryMatic-${{ needs.release_draft.outputs.version }}-${{ matrix.platform }}.mf | |
name: RaspberryMatic-${{ needs.release_draft.outputs.version }}-${{ matrix.platform }}.mf | |
########################################## | |
# Update checksums in release draft | |
update-checksums: | |
permissions: | |
contents: write # ncipollo/release-action | |
name: Update checksums | |
runs-on: ubuntu-22.04 | |
needs: [release_draft, build] | |
steps: | |
- uses: actions/checkout@v4 | |
# download all artifact files | |
- name: Download all workflow artifacts | |
uses: actions/download-artifact@v4 | |
- name: Patch release draft | |
shell: bash | |
run: | | |
for f in */*.mf; do | |
while read -r line; do | |
NEEDLE=$(echo "${line}" | awk '{print $3}' | sed 's/.*-\(.*\..*\)$/\1/') | |
SHACKS=$(echo "${line}" | awk '{print $2}') | |
if [[ "${NEEDLE##*.}" == "ova" ]]; then | |
NEEDLE="ova" | |
fi | |
sed -i "s/XSHA${NEEDLE}X/${SHACKS}/" release-template.md/release-template.md | |
done < <(cat ${f}) | |
done | |
- name: Update release draft | |
uses: ncipollo/release-action@v1.13.0 | |
with: | |
tag: ${{ needs.release_draft.outputs.tag }} | |
bodyFile: release-template.md/release-template.md | |
allowUpdates: true | |
draft: true | |
prerelease: false | |
omitNameDuringUpdate: true | |
omitPrereleaseDuringUpdate: true | |
token: ${{ secrets.GITHUB_TOKEN }} | |
########################################## | |
# OCI/Docker build and registry push step | |
oci-multiarch-build-push: | |
permissions: | |
contents: write # ncipollo/release-action | |
packages: write # docker/build-push-action | |
name: OCI/Docker Build+Push | |
runs-on: ubuntu-22.04 | |
needs: [release_draft, build] | |
steps: | |
- name: Checkout Code | |
uses: actions/checkout@v4 | |
- name: Setup Environment | |
run: | | |
echo "GIT_REF=$(git symbolic-ref -q --short HEAD || git describe --tags --exact-match)" >> $GITHUB_ENV | |
# download OCI platform artifacts | |
- name: Download oci_amd64 artifact | |
uses: actions/download-artifact@v4 | |
with: | |
name: RaspberryMatic-${{ needs.release_draft.outputs.version }}-oci_amd64.tgz | |
- name: Download oci_arm64 artifact | |
uses: actions/download-artifact@v4 | |
with: | |
name: RaspberryMatic-${{ needs.release_draft.outputs.version }}-oci_arm64.tgz | |
- name: Download oci_arm artifact | |
uses: actions/download-artifact@v4 | |
with: | |
name: RaspberryMatic-${{ needs.release_draft.outputs.version }}-oci_arm.tgz | |
- name: Extract OCI artifacts | |
run: | | |
mkdir -p oci_build | |
cd oci_build | |
for f in ../*-oci_*.tgz; do | |
tar --wildcards --strip-components 1 -xf $f "*/layer.tar" | |
mv -f layer.tar $(basename $f .tgz).tar | |
rm -f $f | |
done | |
- name: Build OCI tags | |
shell: bash | |
run: | | |
BASE_TAG="ghcr.io/${{ github.repository_owner }}/raspberrymatic" | |
UNIQUE_TAG="${BASE_TAG}:${{ needs.release_draft.outputs.version }}" | |
BRANCH="${GITHUB_REF##*/}" | |
if [[ ${BRANCH} == 'master' ]]; then | |
BRANCH_TAG="${BASE_TAG}:latest" | |
else | |
BRANCH_TAG="${BASE_TAG}:latest-${BRANCH}" | |
fi | |
echo "unique_tag=${UNIQUE_TAG}" >> $GITHUB_OUTPUT | |
echo "branch_tag=${BRANCH_TAG}" >> $GITHUB_OUTPUT | |
id: extract_branch | |
- name: Set up Docker Buildx | |
id: buildx | |
uses: docker/setup-buildx-action@v3.0.0 | |
with: | |
install: true | |
- name: Login to GitHub Container Registry | |
if: github.event.inputs.skip_build == 'false' | |
uses: docker/login-action@v3.0.0 | |
with: | |
registry: ghcr.io | |
username: ${{ github.repository_owner }} | |
password: ${{ secrets.CR_PAT }} | |
- name: Build and push container image | |
if: github.event.inputs.skip_build == 'false' | |
uses: docker/build-push-action@v5.1.0 | |
id: docker_build | |
with: | |
context: oci_build | |
file: buildroot-external/board/oci/Dockerfile | |
platforms: linux/amd64,linux/arm64,linux/arm/v7 | |
push: true | |
build-args: | | |
tar_prefix=RaspberryMatic-${{ needs.release_draft.outputs.version }}-oci_ | |
labels: | | |
org.opencontainers.image.title=RaspberryMatic | |
org.opencontainers.image.description=Alternative OS for your HomeMatic CCU | |
org.opencontainers.image.vendor=RasperryMatic OpenSource Project | |
org.opencontainers.image.authors=RaspberryMatic OpenSource Team | |
org.opencontainers.image.licenses=Apache-2.0 | |
org.opencontainers.image.url=https://raspberrymatic.de | |
org.opencontainers.image.source=https://github.com/${{ github.repository }} | |
org.opencontainers.image.documentation=https://github.com/${{ github.repository }}/wiki | |
org.opencontainers.image.created=${{ needs.build.outputs.build_datetime }} | |
org.opencontainers.image.ref.name=${{ env.GIT_REF }} | |
org.opencontainers.image.revision=${{ github.sha }} | |
org.opencontainers.image.version=${{ needs.release_draft.outputs.version }} | |
io.hass.name=RaspberryMatic CCU | |
io.hass.description=HomeMatic/homematicIP CCU central based on RaspberryMatic | |
io.hass.url=https://github.com/${{ github.repository }}/tree/master/home-assistant-addon | |
io.hass.version=${{ needs.release_draft.outputs.version }} | |
io.hass.type=addon | |
io.hass.arch=armv7|aarch64|amd64 | |
tags: | | |
${{ steps.extract_branch.outputs.unique_tag }} | |
${{ steps.extract_branch.outputs.branch_tag }} | |
- name: Image digest | |
run: echo ${{ steps.docker_build.outputs.digest }} | |
########################################## | |
# Publish new version to public | |
publish-build: | |
permissions: | |
contents: write # github-actions[bot] repo write access | |
name: Publish build | |
runs-on: ubuntu-22.04 | |
needs: [release_draft, build, oci-multiarch-build-push] | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Bump HomeAssistant add-on version | |
run: | | |
sed -i "s/^\(version:\)\(.*\)/\1 ${{ needs.release_draft.outputs.version }}/" home-assistant-addon/config.yaml | |
# download rpi manifest files | |
- name: Download rpi0 manifest | |
uses: actions/download-artifact@v4 | |
with: | |
name: RaspberryMatic-${{ needs.release_draft.outputs.version }}-rpi0.mf | |
- name: Download rpi2 manifest | |
uses: actions/download-artifact@v4 | |
with: | |
name: RaspberryMatic-${{ needs.release_draft.outputs.version }}-rpi2.mf | |
- name: Download rpi3 manifest | |
uses: actions/download-artifact@v4 | |
with: | |
name: RaspberryMatic-${{ needs.release_draft.outputs.version }}-rpi3.mf | |
- name: Download rpi4 manifest | |
uses: actions/download-artifact@v4 | |
with: | |
name: RaspberryMatic-${{ needs.release_draft.outputs.version }}-rpi4.mf | |
- name: Download rpi5 manifest | |
uses: actions/download-artifact@v4 | |
with: | |
name: RaspberryMatic-${{ needs.release_draft.outputs.version }}-rpi5.mf | |
- name: Bump rpi-imager version | |
run: | | |
release/rpi-imager-update.sh release/rpi-imager.json \ | |
RaspberryMatic-${{ needs.release_draft.outputs.version }}-rpi0.mf \ | |
RaspberryMatic-${{ needs.release_draft.outputs.version }}-rpi2.mf \ | |
RaspberryMatic-${{ needs.release_draft.outputs.version }}-rpi3.mf \ | |
RaspberryMatic-${{ needs.release_draft.outputs.version }}-rpi4.mf \ | |
RaspberryMatic-${{ needs.release_draft.outputs.version }}-rpi5.mf | |
- name: Bump LATEST-VERSION.js | |
run: | | |
echo "homematic.com.setLatestVersion('${{ needs.release_draft.outputs.version }}', 'HM-RASPBERRYMATIC');" >release/LATEST-VERSION.js | |
- name: Bump helm Chart.yaml | |
shell: bash | |
run: | | |
VERSION=${{ needs.release_draft.outputs.version }} | |
sed -i "s/^\(version:\)\(.*\)/\1 ${VERSION::-9}/" helm/raspberrymatic/Chart.yaml | |
sed -i "s/^\(appVersion:\)\(.*\)/\1 ${VERSION}/" helm/raspberrymatic/Chart.yaml | |
sed -i "s|- Release of .*|- Release of ${VERSION} (https://github.com/jens-maus/RaspberryMatic/releases/tag/${VERSION})|" helm/raspberrymatic/Chart.yaml | |
- name: Show git diffs | |
shell: bash | |
run: | | |
git status | |
git diff | |
- name: Commit changes | |
if: github.event.inputs.skip_build == 'false' | |
run: | | |
git config user.name "github-actions" | |
git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
git pull --rebase --autostash | |
git commit -a -m "release bump [${{ needs.release_draft.outputs.version }}]" | |
git push | |
helm: | |
permissions: | |
contents: write # stefanprodan/helm-gh-pages | |
name: Build K8s Helm chart | |
runs-on: ubuntu-22.04 | |
needs: [release_draft, oci-multiarch-build-push, publish-build] | |
steps: | |
- name: Checkout Code | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Publish Helm chart | |
if: github.event.inputs.skip_build == 'false' | |
uses: stefanprodan/helm-gh-pages@master | |
with: | |
token: ${{ secrets.GITHUB_TOKEN }} | |
charts_dir: helm | |
chart_version: ${{ needs.release_draft.outputs.occu_version }} | |
app_version: ${{ needs.release_draft.outputs.version }} |