Skip to content

Release Build

Release Build #103

Workflow file for this run

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