398 lines
13 KiB
YAML
398 lines
13 KiB
YAML
name: Build supervisor
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
channel:
|
|
description: "Channel"
|
|
required: true
|
|
default: "dev"
|
|
version:
|
|
description: "Version"
|
|
required: true
|
|
publish:
|
|
description: "Publish"
|
|
required: true
|
|
default: "false"
|
|
stable:
|
|
description: "Stable"
|
|
required: true
|
|
default: "false"
|
|
pull_request:
|
|
branches: ["main"]
|
|
release:
|
|
types: ["published"]
|
|
push:
|
|
branches: ["main"]
|
|
paths:
|
|
- "rootfs/**"
|
|
- "supervisor/**"
|
|
- build.yaml
|
|
- Dockerfile
|
|
- requirements.txt
|
|
- setup.py
|
|
|
|
env:
|
|
DEFAULT_PYTHON: "3.10"
|
|
BUILD_NAME: supervisor
|
|
BUILD_TYPE: supervisor
|
|
|
|
concurrency:
|
|
group: '${{ github.workflow }}-${{ github.ref }}'
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
init:
|
|
name: Initialize build
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
architectures: ${{ steps.info.outputs.architectures }}
|
|
version: ${{ steps.version.outputs.version }}
|
|
channel: ${{ steps.version.outputs.channel }}
|
|
publish: ${{ steps.version.outputs.publish }}
|
|
requirements: ${{ steps.requirements.outputs.changed }}
|
|
steps:
|
|
- name: Checkout the repository
|
|
uses: actions/checkout@v3.5.0
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Get information
|
|
id: info
|
|
uses: home-assistant/actions/helpers/info@master
|
|
|
|
- name: Get version
|
|
id: version
|
|
uses: home-assistant/actions/helpers/version@master
|
|
with:
|
|
type: ${{ env.BUILD_TYPE }}
|
|
|
|
- name: Get changed files
|
|
id: changed_files
|
|
if: steps.version.outputs.publish == 'false'
|
|
uses: jitterbit/get-changed-files@v1
|
|
|
|
- name: Check if requirements files changed
|
|
id: requirements
|
|
run: |
|
|
if [[ "${{ steps.changed_files.outputs.all }}" =~ (requirements.txt|build.json) ]]; then
|
|
echo "::set-output name=changed::true"
|
|
fi
|
|
|
|
build:
|
|
name: Build ${{ matrix.arch }} supervisor
|
|
needs: init
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
arch: ${{ fromJson(needs.init.outputs.architectures) }}
|
|
steps:
|
|
- name: Checkout the repository
|
|
uses: actions/checkout@v3.5.0
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Write env-file
|
|
if: needs.init.outputs.requirements == 'true'
|
|
run: |
|
|
(
|
|
# Fix out of memory issues with rust
|
|
echo "CARGO_NET_GIT_FETCH_WITH_CLI=true"
|
|
) > .env_file
|
|
|
|
- name: Build wheels
|
|
if: needs.init.outputs.requirements == 'true'
|
|
uses: home-assistant/wheels@2022.10.1
|
|
with:
|
|
abi: cp310
|
|
tag: musllinux_1_2
|
|
arch: ${{ matrix.arch }}
|
|
wheels-key: ${{ secrets.WHEELS_KEY }}
|
|
apk: "libffi-dev;openssl-dev"
|
|
skip-binary: aiohttp
|
|
env-file: true
|
|
requirements: "requirements.txt"
|
|
|
|
- name: Set version
|
|
if: needs.init.outputs.publish == 'true'
|
|
uses: home-assistant/actions/helpers/version@master
|
|
with:
|
|
type: ${{ env.BUILD_TYPE }}
|
|
|
|
- name: Login to DockerHub
|
|
if: needs.init.outputs.publish == 'true'
|
|
uses: docker/login-action@v2.1.0
|
|
with:
|
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
|
|
- name: Login to GitHub Container Registry
|
|
if: needs.init.outputs.publish == 'true'
|
|
uses: docker/login-action@v2.1.0
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.repository_owner }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Set build arguments
|
|
if: needs.init.outputs.publish == 'false'
|
|
run: echo "BUILD_ARGS=--test" >> $GITHUB_ENV
|
|
|
|
- name: Build supervisor
|
|
uses: home-assistant/builder@2023.03.0
|
|
with:
|
|
args: |
|
|
$BUILD_ARGS \
|
|
--${{ matrix.arch }} \
|
|
--target /data \
|
|
--generic ${{ needs.init.outputs.version }}
|
|
env:
|
|
CAS_API_KEY: ${{ secrets.CAS_TOKEN }}
|
|
|
|
codenotary:
|
|
name: CAS signature
|
|
needs: init
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout the repository
|
|
if: needs.init.outputs.publish == 'true'
|
|
uses: actions/checkout@v3.5.0
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
|
if: needs.init.outputs.publish == 'true'
|
|
uses: actions/setup-python@v4.5.0
|
|
with:
|
|
python-version: ${{ env.DEFAULT_PYTHON }}
|
|
|
|
- name: Set version
|
|
if: needs.init.outputs.publish == 'true'
|
|
uses: home-assistant/actions/helpers/version@master
|
|
with:
|
|
type: ${{ env.BUILD_TYPE }}
|
|
|
|
- name: Install dirhash and calc hash
|
|
if: needs.init.outputs.publish == 'true'
|
|
id: dirhash
|
|
run: |
|
|
pip3 install dirhash
|
|
dir_hash="$(dirhash "${{ github.workspace }}/supervisor" -a sha256 --match "*.py")"
|
|
echo "::set-output name=dirhash::${dir_hash}"
|
|
|
|
- name: Signing Source
|
|
if: needs.init.outputs.publish == 'true'
|
|
uses: home-assistant/actions/helpers/codenotary@master
|
|
with:
|
|
source: hash://${{ steps.dirhash.outputs.dirhash }}
|
|
asset: supervisor-${{ needs.init.outputs.version }}
|
|
token: ${{ secrets.CAS_TOKEN }}
|
|
|
|
version:
|
|
name: Update version
|
|
needs: ["init", "run_supervisor"]
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout the repository
|
|
if: needs.init.outputs.publish == 'true'
|
|
uses: actions/checkout@v3.5.0
|
|
|
|
- name: Initialize git
|
|
if: needs.init.outputs.publish == 'true'
|
|
uses: home-assistant/actions/helpers/git-init@master
|
|
with:
|
|
name: ${{ secrets.GIT_NAME }}
|
|
email: ${{ secrets.GIT_EMAIL }}
|
|
token: ${{ secrets.GIT_TOKEN }}
|
|
|
|
- name: Update version file
|
|
if: needs.init.outputs.publish == 'true'
|
|
uses: home-assistant/actions/helpers/version-push@master
|
|
with:
|
|
key: ${{ env.BUILD_NAME }}
|
|
version: ${{ needs.init.outputs.version }}
|
|
channel: ${{ needs.init.outputs.channel }}
|
|
|
|
run_supervisor:
|
|
runs-on: ubuntu-latest
|
|
name: Run the Supervisor
|
|
needs: ["build", "codenotary", "init"]
|
|
timeout-minutes: 60
|
|
steps:
|
|
- name: Checkout the repository
|
|
uses: actions/checkout@v3.5.0
|
|
|
|
- name: Build the Supervisor
|
|
if: needs.init.outputs.publish != 'true'
|
|
uses: home-assistant/builder@2023.03.0
|
|
with:
|
|
args: |
|
|
--test \
|
|
--amd64 \
|
|
--target /data \
|
|
--generic runner
|
|
|
|
- name: Pull Supervisor
|
|
if: needs.init.outputs.publish == 'true'
|
|
run: |
|
|
docker pull ghcr.io/home-assistant/amd64-hassio-supervisor:${{ needs.init.outputs.version }}
|
|
docker tag ghcr.io/home-assistant/amd64-hassio-supervisor:${{ needs.init.outputs.version }} homeassistant/amd64-hassio-supervisor:runner
|
|
|
|
- name: Create the Supervisor
|
|
run: |
|
|
mkdir -p /tmp/supervisor/data
|
|
docker create --name hassio_supervisor \
|
|
--privileged \
|
|
--security-opt seccomp=unconfined \
|
|
--security-opt apparmor=unconfined \
|
|
-v /run/docker.sock:/run/docker.sock \
|
|
-v /run/dbus:/run/dbus \
|
|
-v /tmp/supervisor/data:/data \
|
|
-v /etc/machine-id:/etc/machine-id:ro \
|
|
-e SUPERVISOR_SHARE="/tmp/supervisor/data" \
|
|
-e SUPERVISOR_NAME=hassio_supervisor \
|
|
-e SUPERVISOR_DEV=1 \
|
|
-e SUPERVISOR_MACHINE="qemux86-64" \
|
|
homeassistant/amd64-hassio-supervisor:runner
|
|
|
|
- name: Start the Supervisor
|
|
run: docker start hassio_supervisor
|
|
|
|
- name: Wait for Supervisor to come up
|
|
run: |
|
|
SUPERVISOR=$(docker inspect --format='{{.NetworkSettings.IPAddress}}' hassio_supervisor)
|
|
ping="error"
|
|
while [ "$ping" != "ok" ]; do
|
|
ping=$(curl -sSL "http://$SUPERVISOR/supervisor/ping" | jq -r '.result')
|
|
sleep 5
|
|
done
|
|
|
|
- name: Check the Supervisor
|
|
run: |
|
|
echo "Checking supervisor info"
|
|
test=$(docker exec hassio_cli ha supervisor info --no-progress --raw-json | jq -r '.result')
|
|
if [ "$test" != "ok" ]; then
|
|
exit 1
|
|
fi
|
|
|
|
echo "Checking supervisor network info"
|
|
test=$(docker exec hassio_cli ha network info --no-progress --raw-json | jq -r '.result')
|
|
if [ "$test" != "ok" ]; then
|
|
exit 1
|
|
fi
|
|
|
|
- name: Check the Store / Addon
|
|
run: |
|
|
echo "Install Core SSH Add-on"
|
|
test=$(docker exec hassio_cli ha addons install core_ssh --no-progress --raw-json | jq -r '.result')
|
|
if [ "$test" != "ok" ]; then
|
|
exit 1
|
|
fi
|
|
|
|
# Make sure it actually installed
|
|
test=$(docker exec hassio_cli ha addons info core_ssh --no-progress --raw-json | jq -r '.data.version')
|
|
if [[ "$test" == "null" ]]; then
|
|
exit 1
|
|
fi
|
|
|
|
echo "Start Core SSH Add-on"
|
|
test=$(docker exec hassio_cli ha addons start core_ssh --no-progress --raw-json | jq -r '.result')
|
|
if [ "$test" != "ok" ]; then
|
|
exit 1
|
|
fi
|
|
|
|
# Make sure its state is started
|
|
test="$(docker exec hassio_cli ha addons info core_ssh --no-progress --raw-json | jq -r '.data.state')"
|
|
if [ "$test" != "started" ]; then
|
|
exit 1
|
|
fi
|
|
|
|
- name: Check the Supervisor code sign
|
|
if: needs.init.outputs.publish == 'true'
|
|
run: |
|
|
echo "Enable Content-Trust"
|
|
test=$(docker exec hassio_cli ha security options --content-trust=true --no-progress --raw-json | jq -r '.result')
|
|
if [ "$test" != "ok" ]; then
|
|
exit 1
|
|
fi
|
|
|
|
echo "Run supervisor health check"
|
|
test=$(docker exec hassio_cli ha resolution healthcheck --no-progress --raw-json | jq -r '.result')
|
|
if [ "$test" != "ok" ]; then
|
|
exit 1
|
|
fi
|
|
|
|
echo "Check supervisor unhealthy"
|
|
test=$(docker exec hassio_cli ha resolution info --no-progress --raw-json | jq -r '.data.unhealthy[]')
|
|
if [ "$test" != "" ]; then
|
|
exit 1
|
|
fi
|
|
|
|
echo "Check supervisor supported"
|
|
test=$(docker exec hassio_cli ha resolution info --no-progress --raw-json | jq -r '.data.unsupported[]')
|
|
if [[ "$test" =~ source_mods ]]; then
|
|
exit 1
|
|
fi
|
|
|
|
- name: Create full backup
|
|
id: backup
|
|
run: |
|
|
test=$(docker exec hassio_cli ha backups new --no-progress --raw-json)
|
|
if [ "$(echo $test | jq -r '.result')" != "ok" ]; then
|
|
exit 1
|
|
fi
|
|
echo "::set-output name=slug::$(echo $test | jq -r '.data.slug')"
|
|
|
|
- name: Uninstall SSH add-on
|
|
run: |
|
|
test=$(docker exec hassio_cli ha addons uninstall core_ssh --no-progress --raw-json | jq -r '.result')
|
|
if [ "$test" != "ok" ]; then
|
|
exit 1
|
|
fi
|
|
|
|
- name: Restart supervisor
|
|
run: |
|
|
test=$(docker exec hassio_cli ha supervisor restart --no-progress --raw-json | jq -r '.result')
|
|
if [ "$test" != "ok" ]; then
|
|
exit 1
|
|
fi
|
|
|
|
- name: Wait for Supervisor to come up
|
|
run: |
|
|
SUPERVISOR=$(docker inspect --format='{{.NetworkSettings.IPAddress}}' hassio_supervisor)
|
|
ping="error"
|
|
while [ "$ping" != "ok" ]; do
|
|
ping=$(curl -sSL "http://$SUPERVISOR/supervisor/ping" | jq -r '.result')
|
|
sleep 5
|
|
done
|
|
|
|
- name: Restore SSH add-on from backup
|
|
run: |
|
|
test=$(docker exec hassio_cli ha backups restore ${{ steps.backup.outputs.slug }} --addons core_ssh --no-progress --raw-json | jq -r '.result')
|
|
if [ "$test" != "ok" ]; then
|
|
exit 1
|
|
fi
|
|
|
|
# Make sure it actually installed
|
|
test=$(docker exec hassio_cli ha addons info core_ssh --no-progress --raw-json | jq -r '.data.version')
|
|
if [[ "$test" == "null" ]]; then
|
|
exit 1
|
|
fi
|
|
|
|
# Make sure its state is started
|
|
test="$(docker exec hassio_cli ha addons info core_ssh --no-progress --raw-json | jq -r '.data.state')"
|
|
if [ "$test" != "started" ]; then
|
|
exit 1
|
|
fi
|
|
|
|
- name: Restore SSL directory from backup
|
|
run: |
|
|
test=$(docker exec hassio_cli ha backups restore ${{ steps.backup.outputs.slug }} --folders ssl --no-progress --raw-json | jq -r '.result')
|
|
if [ "$test" != "ok" ]; then
|
|
exit 1
|
|
fi
|
|
|
|
- name: Get supervisor logs on failiure
|
|
if: ${{ cancelled() || failure() }}
|
|
run: docker logs hassio_supervisor
|