diff --git a/.github/workflows/builder.yml b/.github/workflows/builder.yml new file mode 100644 index 00000000000..c5eccbf9b2a --- /dev/null +++ b/.github/workflows/builder.yml @@ -0,0 +1,310 @@ +name: Build images + +# yamllint disable-line rule:truthy +on: + release: + types: ["published"] + schedule: + - cron: "0 2 * * *" + +env: + BUILD_TYPE: core + DEFAULT_PYTHON: 3.8 + +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 }} + steps: + - name: Checkout the repository + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up Python ${{ env.DEFAULT_PYTHON }} + uses: actions/setup-python@v2.2.1 + with: + python-version: ${{ env.DEFAULT_PYTHON }} + + - 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: Verify version + uses: home-assistant/actions/helpers/verify-version@master + with: + ignore-dev: true + + build_python: + name: Build PyPi package + needs: init + runs-on: ubuntu-latest + if: needs.init.outputs.publish == "true" + steps: + - name: Checkout the repository + uses: actions/checkout@v2 + + - name: Set up Python ${{ env.DEFAULT_PYTHON }} + uses: actions/setup-python@v2.2.1 + with: + python-version: ${{ env.DEFAULT_PYTHON }} + + - name: Build package + shell: bash + run: | + pip install twine wheel + python setup.py sdist bdist_wheel + + - name: Upload package + shell: bash + run: | + export TWINE_USERNAME="__token__" + export TWINE_PASSWORD="${{ secrets.TWINE_TOKEN }}" + + twine upload dist/* --skip-existing + + build_base: + name: Build ${{ matrix.arch }} base core image + needs: init + runs-on: ubuntu-latest + strategy: + matrix: + arch: ${{ fromJson(needs.init.outputs.architectures) }} + steps: + - name: Checkout the repository + uses: actions/checkout@v2 + + - name: Set up Python ${{ env.DEFAULT_PYTHON }} + if: needs.init.outputs.channel == "dev" + uses: actions/setup-python@v2.2.1 + with: + python-version: ${{ env.DEFAULT_PYTHON }} + + - name: Adjust nightly version + if: needs.init.outputs.channel == "dev" + shell: bash + run: | + python3 -m pip install packaging + python3 -m pip install . + python3 script/version_bump.py nightly + version="$(python setup.py -V)" + + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build base image + uses: home-assistant/builder@2021.04.2 + with: + args: | + $BUILD_ARGS \ + --${{ matrix.arch }} \ + --target /data \ + --with-codenotary "${{ secrets.VCN_USER }}" "${{ secrets.VCN_PASSWORD }}" "${{ secrets.VCN_ORG }}" \ + --validate-from "${{ secrets.VCN_ORG }}" \ + --generic ${{ needs.init.outputs.version }} + + build_machine: + name: Build ${{ matrix.arch }} machine core image + needs: ["init", "build_base"] + runs-on: ubuntu-latest + strategy: + matrix: + machine: + - generic-x86-64 + - intel-nuc + - odroid-c4 + - odroid-n2 + - odroid-xu + - qemuarm + - qemuarm-64 + - qemux86 + - qemux86-64 + - raspberrypi + - raspberrypi2 + - raspberrypi3 + - raspberrypi3-64 + - raspberrypi4 + - raspberrypi4-64 + - tinker + steps: + - name: Checkout the repository + uses: actions/checkout@v2 + + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build base image + uses: home-assistant/builder@2021.04.2 + with: + args: | + $BUILD_ARGS \ + --${{ matrix.arch }} \ + --target /data/machine \ + --with-codenotary "${{ secrets.VCN_USER }}" "${{ secrets.VCN_PASSWORD }}" "${{ secrets.VCN_ORG }}" \ + --validate-from "${{ secrets.VCN_ORG }}" \ + --machine "${{ needs.init.outputs.version }}=${{ matrix.machine }}"" + + publish_ha: + name: Publish version files + needs: ["init", "build_machine"] + runs-on: ubuntu-latest + steps: + - name: Checkout the repository + uses: actions/checkout@v2 + + - name: Initialize git + 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 + uses: home-assistant/actions/helpers/version-push@master + with: + key: "homeassistant[]" + key-description: "Home Assistant Core" + version: ${{ needs.init.outputs.version }} + channel: ${{ needs.init.outputs.channel }} + + - name: Update version file (stable -> beta) + if: needs.init.outputs.channel == "stable" + uses: home-assistant/actions/helpers/version-push@master + with: + key: "homeassistant[]" + key-description: "Home Assistant Core" + version: ${{ needs.init.outputs.version }} + channel: beta + + publish_container: + name: Publish meta container + needs: ["init", "build_base"] + runs-on: ubuntu-latest + steps: + - name: Checkout the repository + uses: actions/checkout@v2 + + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build Meta Image + shell: bash + run: | + bash <(curl https://getvcn.codenotary.com -L) + + export DOCKER_CLI_EXPERIMENTAL=enabled + + function create_manifest() { + local docker_reg={1} + local tag_l=${2} + local tag_r=${3} + + docker manifest create "${docker_reg}/home-assistant:${tag_l}" \ + "${docker_reg}/amd64-homeassistant:${tag_r}" \ + "${docker_reg}/i386-homeassistant:${tag_r}" \ + "${docker_reg}/armhf-homeassistant:${tag_r}" \ + "${docker_reg}/armv7-homeassistant:${tag_r}" \ + "${docker_reg}/aarch64-homeassistant:${tag_r}" + + docker manifest annotate "${docker_reg}/home-assistant:${tag_l}" \ + "${docker_reg}/amd64-homeassistant:${tag_r}" \ + --os linux --arch amd64 + + docker manifest annotate "${docker_reg}/home-assistant:${tag_l}" \ + "${docker_reg}/i386-homeassistant:${tag_r}" \ + --os linux --arch 386 + + docker manifest annotate "${docker_reg}/home-assistant:${tag_l}" \ + "${docker_reg}/armhf-homeassistant:${tag_r}" \ + --os linux --arch arm --variant=v6 + + docker manifest annotate "${docker_reg}/home-assistant:${tag_l}" \ + "${docker_reg}/armv7-homeassistant:${tag_r}" \ + --os linux --arch arm --variant=v7 + + docker manifest annotate "${docker_reg}/home-assistant:${tag_l}" \ + "${docker_reg}/aarch64-homeassistant:${tag_r}" \ + --os linux --arch arm64 --variant=v8 + + docker manifest push --purge "${docker_reg}/home-assistant:${tag_l}" + } + + function validate_image() { + local image={1} + state="$(vcn authenticate --org home-assistant.io --output json docker://${image} | jq '.verification.status // 2')" + if [[ "${state}" != "0" ]]; then + echo "Invalid signature!" + exit 1 + fi + } + + for docker_reg in "homeassistant" "ghcr.io/home-assistant"; do + docker pull "${docker_reg}/amd64-homeassistant:${{ needs.init.outputs.version }}" + docker pull "${docker_reg}/i386-homeassistant:${{ needs.init.outputs.version }}" + docker pull "${docker_reg}/armhf-homeassistant:${{ needs.init.outputs.version }}" + docker pull "${docker_reg}/armv7-homeassistant:${{ needs.init.outputs.version }}" + docker pull "${docker_reg}/aarch64-homeassistant:${{ needs.init.outputs.version }}" + + validate_image "${docker_reg}/amd64-homeassistant:${{ needs.init.outputs.version }}" + validate_image "${docker_reg}/i386-homeassistant:${{ needs.init.outputs.version }}" + validate_image "${docker_reg}/armhf-homeassistant:${{ needs.init.outputs.version }}" + validate_image "${docker_reg}/armv7-homeassistant:${{ needs.init.outputs.version }}" + validate_image "${docker_reg}/aarch64-homeassistant:${{ needs.init.outputs.version }}" + + # Create version tag + create_manifest "${docker_reg}" "${{ needs.init.outputs.version }}" "${{ needs.init.outputs.version }}" + + # Create general tags + if [[ "${{ needs.init.outputs.version }}" =~ d ]]; then + create_manifest "${docker_reg}" "dev" "${{ needs.init.outputs.version }}" + elif [[ "${{ needs.init.outputs.version }}" =~ b ]]; then + create_manifest "${docker_reg}" "beta" "${{ needs.init.outputs.version }}" + create_manifest "${docker_reg}" "rc" "${{ needs.init.outputs.version }}" + else + create_manifest "${docker_reg}" "stable" "${{ needs.init.outputs.version }}" + create_manifest "${docker_reg}" "latest" "${{ needs.init.outputs.version }}" + create_manifest "${docker_reg}" "beta" "${{ needs.init.outputs.version }}" + create_manifest "${docker_reg}" "rc" "${{ needs.init.outputs.version }}" + fi + done diff --git a/azure-pipelines-release.yml b/azure-pipelines-release.yml deleted file mode 100644 index 74aa05e58f3..00000000000 --- a/azure-pipelines-release.yml +++ /dev/null @@ -1,323 +0,0 @@ -# https://dev.azure.com/home-assistant - -trigger: - tags: - include: - - '*' -pr: none -schedules: - - cron: "0 1 * * *" - displayName: "nightly builds" - branches: - include: - - dev - always: true -variables: - - name: versionBuilder - value: '2021.02.0' - - group: docker - - group: github - - group: twine -resources: - repositories: - - repository: azure - type: github - name: 'home-assistant/ci-azure' - endpoint: 'home-assistant' - -stages: - -- stage: 'Validate' - jobs: - - template: templates/azp-job-version.yaml@azure - parameters: - ignoreDev: true - - job: 'Permission' - pool: - vmImage: 'ubuntu-latest' - steps: - - script: | - sudo apt-get install -y --no-install-recommends \ - jq curl - - release="$(Build.SourceBranchName)" - created_by="$(curl -s https://api.github.com/repos/home-assistant/core/releases/tags/${release} | jq --raw-output '.author.login')" - - if [[ "${created_by}" =~ ^(balloob|pvizeli|fabaff|robbiet480|bramkragten|frenck)$ ]]; then - exit 0 - fi - - echo "${created_by} is not allowed to create an release!" - exit 1 - displayName: 'Check rights' - condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags')) - -- stage: 'Build' - jobs: - - job: 'ReleasePython' - condition: startsWith(variables['Build.SourceBranch'], 'refs/tags') - pool: - vmImage: 'ubuntu-latest' - steps: - - task: UsePythonVersion@0 - displayName: 'Use Python 3.8' - inputs: - versionSpec: '3.8' - - script: pip install twine wheel - displayName: 'Install tools' - - script: python setup.py sdist bdist_wheel - displayName: 'Build package' - - script: | - export TWINE_USERNAME="$(twineUser)" - export TWINE_PASSWORD="$(twinePassword)" - - twine upload dist/* --skip-existing - displayName: 'Upload pypi' - - job: 'ReleaseDocker' - timeoutInMinutes: 240 - pool: - vmImage: 'ubuntu-latest' - strategy: - maxParallel: 5 - matrix: - amd64: - buildArch: 'amd64' - i386: - buildArch: 'i386' - armhf: - buildArch: 'armhf' - armv7: - buildArch: 'armv7' - aarch64: - buildArch: 'aarch64' - steps: - - template: templates/azp-step-ha-version.yaml@azure - - script: | - docker login -u $(dockerUser) -p $(dockerPassword) - displayName: 'Docker hub login' - - script: docker pull homeassistant/amd64-builder:$(versionBuilder) - displayName: 'Install Builder' - - script: | - set -e - - docker run --rm --privileged \ - -v ~/.docker:/root/.docker:rw \ - -v /run/docker.sock:/run/docker.sock:rw \ - -v $(pwd):/data:ro \ - homeassistant/amd64-builder:$(versionBuilder) \ - --generic $(homeassistantRelease) "--$(buildArch)" -t /data \ - displayName: 'Build Release' - - job: 'ReleaseMachine' - dependsOn: - - ReleaseDocker - timeoutInMinutes: 240 - pool: - vmImage: 'ubuntu-latest' - strategy: - maxParallel: 17 - matrix: - qemux86-64: - buildMachine: 'qemux86-64' - generic-x86-64: - buildMachine: 'generic-x86-64' - intel-nuc: - buildMachine: 'intel-nuc' - qemux86: - buildMachine: 'qemux86' - qemuarm: - buildMachine: 'qemuarm' - raspberrypi: - buildMachine: 'raspberrypi' - raspberrypi2: - buildMachine: 'raspberrypi2' - raspberrypi3: - buildMachine: 'raspberrypi3' - raspberrypi4: - buildMachine: 'raspberrypi4' - odroid-xu: - buildMachine: 'odroid-xu' - tinker: - buildMachine: 'tinker' - qemuarm-64: - buildMachine: 'qemuarm-64' - raspberrypi3-64: - buildMachine: 'raspberrypi3-64' - raspberrypi4-64: - buildMachine: 'raspberrypi4-64' - odroid-c2: - buildMachine: 'odroid-c2' - odroid-c4: - buildMachine: 'odroid-c4' - odroid-n2: - buildMachine: 'odroid-n2' - steps: - - template: templates/azp-step-ha-version.yaml@azure - - script: | - docker login -u $(dockerUser) -p $(dockerPassword) - displayName: 'Docker hub login' - - script: docker pull homeassistant/amd64-builder:$(versionBuilder) - displayName: 'Install Builder' - - script: | - set -e - - docker run --rm --privileged \ - -v ~/.docker:/root/.docker \ - -v /run/docker.sock:/run/docker.sock:rw \ - -v $(pwd):/data:ro \ - homeassistant/amd64-builder:$(versionBuilder) \ - --homeassistant-machine "$(homeassistantRelease)=$(buildMachine)" \ - -t /data/machine --docker-hub homeassistant - displayName: 'Build Machine' - -- stage: 'Publish' - jobs: - - job: 'ReleaseHassio' - pool: - vmImage: 'ubuntu-latest' - steps: - - template: templates/azp-step-ha-version.yaml@azure - - script: | - sudo apt-get install -y --no-install-recommends \ - git jq curl - - git config --global user.name "Pascal Vizeli" - git config --global user.email "pvizeli@syshack.ch" - git config --global credential.helper store - - echo "https://$(githubToken):x-oauth-basic@github.com" > $HOME/.git-credentials - displayName: 'Install requirements' - - script: | - set -e - - version="$(homeassistantRelease)" - - git clone https://github.com/home-assistant/version - cd version - - dev_version="$(jq --raw-output '.homeassistant.default' dev.json)" - beta_version="$(jq --raw-output '.homeassistant.default' beta.json)" - stable_version="$(jq --raw-output '.homeassistant.default' stable.json)" - - if [[ "$version" =~ d ]]; then - sed -i "s|$dev_version|$version|g" dev.json - elif [[ "$version" =~ b ]]; then - sed -i "s|$beta_version|$version|g" beta.json - else - sed -i "s|$beta_version|$version|g" beta.json - sed -i "s|$stable_version|$version|g" stable.json - fi - - git commit -am "Bump Home Assistant $version" - git push - displayName: "Update version files" - - job: 'ReleaseDocker' - pool: - vmImage: 'ubuntu-latest' - steps: - - template: templates/azp-step-ha-version.yaml@azure - - script: | - docker login -u $(dockerUser) -p $(dockerPassword) - displayName: 'Docker login' - - script: | - set -e - export DOCKER_CLI_EXPERIMENTAL=enabled - - function create_manifest() { - local tag_l=$1 - local tag_r=$2 - - docker manifest create homeassistant/home-assistant:${tag_l} \ - homeassistant/amd64-homeassistant:${tag_r} \ - homeassistant/i386-homeassistant:${tag_r} \ - homeassistant/armhf-homeassistant:${tag_r} \ - homeassistant/armv7-homeassistant:${tag_r} \ - homeassistant/aarch64-homeassistant:${tag_r} - - docker manifest annotate homeassistant/home-assistant:${tag_l} \ - homeassistant/amd64-homeassistant:${tag_r} \ - --os linux --arch amd64 - - docker manifest annotate homeassistant/home-assistant:${tag_l} \ - homeassistant/i386-homeassistant:${tag_r} \ - --os linux --arch 386 - - docker manifest annotate homeassistant/home-assistant:${tag_l} \ - homeassistant/armhf-homeassistant:${tag_r} \ - --os linux --arch arm --variant=v6 - - docker manifest annotate homeassistant/home-assistant:${tag_l} \ - homeassistant/armv7-homeassistant:${tag_r} \ - --os linux --arch arm --variant=v7 - - docker manifest annotate homeassistant/home-assistant:${tag_l} \ - homeassistant/aarch64-homeassistant:${tag_r} \ - --os linux --arch arm64 --variant=v8 - - docker manifest push --purge homeassistant/home-assistant:${tag_l} - } - - docker pull homeassistant/amd64-homeassistant:$(homeassistantRelease) - docker pull homeassistant/i386-homeassistant:$(homeassistantRelease) - docker pull homeassistant/armhf-homeassistant:$(homeassistantRelease) - docker pull homeassistant/armv7-homeassistant:$(homeassistantRelease) - docker pull homeassistant/aarch64-homeassistant:$(homeassistantRelease) - - # Create version tag - create_manifest "$(homeassistantRelease)" "$(homeassistantRelease)" - - # Create general tags - if [[ "$(homeassistantRelease)" =~ d ]]; then - create_manifest "dev" "$(homeassistantRelease)" - elif [[ "$(homeassistantRelease)" =~ b ]]; then - create_manifest "beta" "$(homeassistantRelease)" - create_manifest "rc" "$(homeassistantRelease)" - else - create_manifest "stable" "$(homeassistantRelease)" - create_manifest "latest" "$(homeassistantRelease)" - create_manifest "beta" "$(homeassistantRelease)" - create_manifest "rc" "$(homeassistantRelease)" - fi - - displayName: 'Create Meta-Image' - -- stage: 'Addidional' - jobs: - - job: 'Updater' - pool: - vmImage: 'ubuntu-latest' - variables: - - group: gcloud - steps: - - template: templates/azp-step-ha-version.yaml@azure - - script: | - set -e - - export CLOUDSDK_CORE_DISABLE_PROMPTS=1 - - curl -o google-cloud-sdk.tar.gz https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz - tar -C . -xvf google-cloud-sdk.tar.gz - rm -f google-cloud-sdk.tar.gz - ./google-cloud-sdk/install.sh - displayName: 'Setup gCloud' - condition: eq(variables['homeassistantReleaseStable'], 'true') - - script: | - set -e - - export CLOUDSDK_CORE_DISABLE_PROMPTS=1 - - echo "$(gcloudAnalytic)" > gcloud_auth.json - ./google-cloud-sdk/bin/gcloud auth activate-service-account --key-file gcloud_auth.json - rm -f gcloud_auth.json - displayName: 'Auth gCloud' - condition: eq(variables['homeassistantReleaseStable'], 'true') - - script: | - set -e - - export CLOUDSDK_CORE_DISABLE_PROMPTS=1 - - ./google-cloud-sdk/bin/gcloud functions deploy Analytics-Receiver \ - --project home-assistant-analytics \ - --update-env-vars VERSION=$(homeassistantRelease) \ - --source gs://analytics-src/function-source.zip - displayName: 'Push details to updater' - condition: eq(variables['homeassistantReleaseStable'], 'true') diff --git a/build.json b/build.json index 0183b61c67c..eeeb1f9150d 100644 --- a/build.json +++ b/build.json @@ -1,14 +1,22 @@ { "image": "homeassistant/{arch}-homeassistant", + "shadow_repository": "ghcr.io/home-assistant", "build_from": { - "aarch64": "homeassistant/aarch64-homeassistant-base:2021.02.0", - "armhf": "homeassistant/armhf-homeassistant-base:2021.02.0", - "armv7": "homeassistant/armv7-homeassistant-base:2021.02.0", - "amd64": "homeassistant/amd64-homeassistant-base:2021.02.0", - "i386": "homeassistant/i386-homeassistant-base:2021.02.0" + "aarch64": "ghcr.io/home-assistant/aarch64-homeassistant-base:2021.04.2", + "armhf": "ghcr.io/home-assistant/armhf-homeassistant-base:2021.04.2", + "armv7": "ghcr.io/home-assistant/armv7-homeassistant-base:2021.04.2", + "amd64": "ghcr.io/home-assistant/amd64-homeassistant-base:2021.04.2", + "i386": "ghcr.io/home-assistant/i386-homeassistant-base:2021.04.2" }, "labels": { - "io.hass.type": "core" + "io.hass.type": "core", + "org.opencontainers.image.title": "Home Assistant", + "org.opencontainers.image.description": "Open-source home automation platform running on Python 3", + "org.opencontainers.image.source": "https://github.com/home-assistant/core", + "org.opencontainers.image.authors": "The Home Assistant Authors", + "org.opencontainers.image.url": "https://www.home-assistant.io/", + "org.opencontainers.image.documentation": "https://www.home-assistant.io/docs/", + "org.opencontainers.image.licenses": "Apache License 2.0" }, "version_tag": true } diff --git a/machine/build.json b/machine/build.json new file mode 100644 index 00000000000..3b4d804dc1c --- /dev/null +++ b/machine/build.json @@ -0,0 +1,16 @@ +{ + "image": "homeassistant/{machine}-homeassistant", + "shadow_repository": "ghcr.io/home-assistant", + "build_from": { + "aarch64": "ghcr.io/home-assistant/aarch64-homeassistant:", + "armv7": "ghcr.io/home-assistant/armv7-homeassistant:", + "armhf": "ghcr.io/home-assistant/armhf-homeassistant:", + "amd64": "ghcr.io/home-assistant/amd64-homeassistant:", + "i386": "ghcr.io/home-assistant/i386-homeassistant:" + }, + "labels": { + "io.hass.type": "core", + "org.opencontainers.image.source": "https://github.com/home-assistant/core" + }, + "version_tag": true +} diff --git a/rootfs/etc/services.d/home-assistant/run b/rootfs/etc/services.d/home-assistant/run index 11af113e4b9..e1e1f075fb9 100644 --- a/rootfs/etc/services.d/home-assistant/run +++ b/rootfs/etc/services.d/home-assistant/run @@ -5,8 +5,8 @@ cd /config || bashio::exit.nok "Can't find config folder!" -# Enable Jemalloc for Home Assistant Core, unless disabled -if [[ -z "${DISABLE_JEMALLOC+x}" ]]; then - export LD_PRELOAD="/usr/local/lib/libjemalloc.so.2" +# Enable mimalloc for Home Assistant Core, unless disabled +if [[ -z "${DISABLE_MIMALLOC+x}" ]]; then + export LD_PRELOAD="/usr/local/lib/libmimalloc.so" fi exec python3 -m homeassistant --config /config