mirror of
https://github.com/esphome/esphome.git
synced 2024-11-22 06:58:11 +01:00
Refactor docker build system and workflows (#2023)
This commit is contained in:
parent
45d368e3a1
commit
cc7dbeada6
13 changed files with 456 additions and 708 deletions
41
.github/workflows/ci-docker.yml
vendored
41
.github/workflows/ci-docker.yml
vendored
|
@ -18,38 +18,23 @@ jobs:
|
||||||
name: Build docker containers
|
name: Build docker containers
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
matrix:
|
||||||
arch: [amd64, armv7, aarch64]
|
arch: [amd64, armv7, aarch64]
|
||||||
build_type: ["hassio", "docker"]
|
build_type: ["ha-addon", "docker", "lint"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up env variables
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
|
- name: Set TAG
|
||||||
run: |
|
run: |
|
||||||
base_version="3.4.0"
|
echo "TAG=check" >> $GITHUB_ENV
|
||||||
|
|
||||||
if [[ "${{ matrix.build_type }}" == "hassio" ]]; then
|
- name: Run build
|
||||||
build_from="esphome/esphome-hassio-base-${{ matrix.arch }}:${base_version}"
|
|
||||||
build_to="esphome/esphome-hassio-${{ matrix.arch }}"
|
|
||||||
dockerfile="docker/Dockerfile.hassio"
|
|
||||||
else
|
|
||||||
build_from="esphome/esphome-base-${{ matrix.arch }}:${base_version}"
|
|
||||||
build_to="esphome/esphome-${{ matrix.arch }}"
|
|
||||||
dockerfile="docker/Dockerfile"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "BUILD_FROM=${build_from}" >> $GITHUB_ENV
|
|
||||||
echo "BUILD_TO=${build_to}" >> $GITHUB_ENV
|
|
||||||
echo "DOCKERFILE=${dockerfile}" >> $GITHUB_ENV
|
|
||||||
- name: Pull for cache
|
|
||||||
run: |
|
run: |
|
||||||
docker pull "${BUILD_TO}:dev" || true
|
docker/build.py \
|
||||||
- name: Register QEMU binfmt
|
--tag "${TAG}" \
|
||||||
run: docker run --rm --privileged multiarch/qemu-user-static:5.2.0-2 --reset -p yes
|
--arch "${{ matrix.arch }}" \
|
||||||
- run: |
|
--build-type "${{ matrix.build_type }}" \
|
||||||
docker build \
|
build
|
||||||
--build-arg "BUILD_FROM=${BUILD_FROM}" \
|
|
||||||
--build-arg "BUILD_VERSION=ci" \
|
|
||||||
--cache-from "${BUILD_TO}:dev" \
|
|
||||||
--file "${DOCKERFILE}" \
|
|
||||||
.
|
|
||||||
|
|
178
.github/workflows/ci.yml
vendored
178
.github/workflows/ci.yml
vendored
|
@ -4,40 +4,36 @@ name: CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
# On dev branch release-dev already performs CI checks
|
branches: [dev, beta, release]
|
||||||
# On other branches the `pull_request` trigger will be used
|
|
||||||
branches: [beta, release]
|
|
||||||
|
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint-clang-format:
|
ci-with-container:
|
||||||
|
name: ${{ matrix.name }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# cpp lint job runs with esphome-lint docker image so that clang-format-*
|
|
||||||
# doesn't have to be installed
|
|
||||||
container: esphome/esphome-lint:1.1
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
# Set up the pio project so that the cpp checks know how files are compiled
|
|
||||||
# (build flags, libraries etc)
|
|
||||||
- name: Set up platformio environment
|
|
||||||
run: pio init --ide atom
|
|
||||||
|
|
||||||
- name: Run clang-format
|
|
||||||
run: script/clang-format -i
|
|
||||||
- name: Suggest changes
|
|
||||||
run: script/ci-suggest-changes
|
|
||||||
|
|
||||||
lint-clang-tidy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
# cpp lint job runs with esphome-lint docker image so that clang-format-*
|
|
||||||
# doesn't have to be installed
|
|
||||||
container: esphome/esphome-lint:1.1
|
|
||||||
# Split clang-tidy check into 4 jobs. Each one will check 1/4th of the .cpp files
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
split: [1, 2, 3, 4]
|
include:
|
||||||
|
- id: clang-format
|
||||||
|
name: Run script/clang-format
|
||||||
|
- id: clang-tidy
|
||||||
|
name: Run script/clang-tidy 1/4
|
||||||
|
split: 1
|
||||||
|
- id: clang-tidy
|
||||||
|
name: Run script/clang-tidy 2/4
|
||||||
|
split: 2
|
||||||
|
- id: clang-tidy
|
||||||
|
name: Run script/clang-tidy 3/4
|
||||||
|
split: 3
|
||||||
|
- id: clang-tidy
|
||||||
|
name: Run script/clang-tidy 4/4
|
||||||
|
split: 4
|
||||||
|
|
||||||
|
# cpp lint job runs with esphome-lint docker image so that clang-format-*
|
||||||
|
# doesn't have to be installed
|
||||||
|
container: esphome/esphome-lint:1.1
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
# Set up the pio project so that the cpp checks know how files are compiled
|
# Set up the pio project so that the cpp checks know how files are compiled
|
||||||
|
@ -45,26 +41,57 @@ jobs:
|
||||||
- name: Set up platformio environment
|
- name: Set up platformio environment
|
||||||
run: pio init --ide atom
|
run: pio init --ide atom
|
||||||
|
|
||||||
|
|
||||||
- name: Register problem matchers
|
- name: Register problem matchers
|
||||||
run: |
|
run: |
|
||||||
echo "::add-matcher::.github/workflows/matchers/clang-tidy.json"
|
echo "::add-matcher::.github/workflows/matchers/clang-tidy.json"
|
||||||
echo "::add-matcher::.github/workflows/matchers/gcc.json"
|
echo "::add-matcher::.github/workflows/matchers/gcc.json"
|
||||||
|
|
||||||
|
- name: Run clang-format
|
||||||
|
run: script/clang-format -i
|
||||||
|
if: ${{ matrix.id == 'clang-format' }}
|
||||||
|
|
||||||
- name: Run clang-tidy
|
- name: Run clang-tidy
|
||||||
run: script/clang-tidy --all-headers --fix --split-num 4 --split-at ${{ matrix.split }}
|
run: script/clang-tidy --all-headers --fix --split-num 4 --split-at ${{ matrix.split }}
|
||||||
|
if: ${{ matrix.id == 'clang-tidy' }}
|
||||||
|
|
||||||
- name: Suggest changes
|
- name: Suggest changes
|
||||||
run: script/ci-suggest-changes
|
run: script/ci-suggest-changes
|
||||||
|
|
||||||
lint-python:
|
ci:
|
||||||
# Don't use the esphome-lint docker image because it may contain outdated requirements.
|
# Don't use the esphome-lint docker image because it may contain outdated requirements.
|
||||||
# This way, all dependencies are cached via the cache action.
|
# This way, all dependencies are cached via the cache action.
|
||||||
|
name: ${{ matrix.name }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- id: ci-custom
|
||||||
|
name: Run script/ci-custom
|
||||||
|
- id: lint-python
|
||||||
|
name: Run script/lint-python
|
||||||
|
- id: test
|
||||||
|
file: tests/test1.yaml
|
||||||
|
name: Test tests/test1.yaml
|
||||||
|
- id: test
|
||||||
|
file: tests/test2.yaml
|
||||||
|
name: Test tests/test2.yaml
|
||||||
|
- id: test
|
||||||
|
file: tests/test3.yaml
|
||||||
|
name: Test tests/test3.yaml
|
||||||
|
- id: test
|
||||||
|
file: tests/test4.yaml
|
||||||
|
name: Test tests/test4.yaml
|
||||||
|
- id: pytest
|
||||||
|
name: Run pytest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: '3.7'
|
python-version: '3.7'
|
||||||
|
|
||||||
- name: Cache pip modules
|
- name: Cache pip modules
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v1
|
||||||
with:
|
with:
|
||||||
|
@ -72,6 +99,17 @@ jobs:
|
||||||
key: esphome-pip-3.7-${{ hashFiles('setup.py') }}
|
key: esphome-pip-3.7-${{ hashFiles('setup.py') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
esphome-pip-3.7-
|
esphome-pip-3.7-
|
||||||
|
|
||||||
|
# Use per test platformio cache because tests have different platform versions
|
||||||
|
- name: Cache ~/.platformio
|
||||||
|
uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: ~/.platformio
|
||||||
|
key: test-home-platformio-${{ matrix.file }}-${{ hashFiles('esphome/core/config.py') }}
|
||||||
|
restore-keys: |
|
||||||
|
test-home-platformio-${{ matrix.file }}-
|
||||||
|
if: ${{ matrix.id == 'test' }}
|
||||||
|
|
||||||
- name: Set up python environment
|
- name: Set up python environment
|
||||||
run: script/setup
|
run: script/setup
|
||||||
|
|
||||||
|
@ -80,82 +118,22 @@ jobs:
|
||||||
echo "::add-matcher::.github/workflows/matchers/ci-custom.json"
|
echo "::add-matcher::.github/workflows/matchers/ci-custom.json"
|
||||||
echo "::add-matcher::.github/workflows/matchers/lint-python.json"
|
echo "::add-matcher::.github/workflows/matchers/lint-python.json"
|
||||||
echo "::add-matcher::.github/workflows/matchers/python.json"
|
echo "::add-matcher::.github/workflows/matchers/python.json"
|
||||||
|
echo "::add-matcher::.github/workflows/matchers/pytest.json"
|
||||||
|
echo "::add-matcher::.github/workflows/matchers/gcc.json"
|
||||||
|
|
||||||
- name: Lint Custom
|
- name: Lint Custom
|
||||||
run: script/ci-custom.py
|
run: |
|
||||||
|
script/ci-custom.py
|
||||||
|
script/build_codeowners.py --check
|
||||||
|
if: ${{ matrix.id == 'ci-custom' }}
|
||||||
- name: Lint Python
|
- name: Lint Python
|
||||||
run: script/lint-python
|
run: script/lint-python
|
||||||
- name: Lint CODEOWNERS
|
if: ${{ matrix.id == 'lint-python' }}
|
||||||
run: script/build_codeowners.py --check
|
|
||||||
|
|
||||||
test:
|
- run: esphome compile ${{ matrix.file }}
|
||||||
runs-on: ubuntu-latest
|
if: ${{ matrix.id == 'test' }}
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
test:
|
|
||||||
- test1
|
|
||||||
- test2
|
|
||||||
- test3
|
|
||||||
- test4
|
|
||||||
- test5
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: '3.7'
|
|
||||||
- name: Cache pip modules
|
|
||||||
uses: actions/cache@v1
|
|
||||||
with:
|
|
||||||
path: ~/.cache/pip
|
|
||||||
key: esphome-pip-3.7-${{ hashFiles('setup.py') }}
|
|
||||||
restore-keys: |
|
|
||||||
esphome-pip-3.7-
|
|
||||||
# Use per test platformio cache because tests have different platform versions
|
|
||||||
- name: Cache ~/.platformio
|
|
||||||
uses: actions/cache@v1
|
|
||||||
with:
|
|
||||||
path: ~/.platformio
|
|
||||||
key: test-home-platformio-${{ matrix.test }}-${{ hashFiles('esphome/core/config.py') }}
|
|
||||||
restore-keys: |
|
|
||||||
test-home-platformio-${{ matrix.test }}-
|
|
||||||
- name: Set up environment
|
|
||||||
run: script/setup
|
|
||||||
|
|
||||||
|
|
||||||
- name: Register problem matchers
|
|
||||||
run: |
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/gcc.json"
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/python.json"
|
|
||||||
- run: esphome compile tests/${{ matrix.test }}.yaml
|
|
||||||
|
|
||||||
pytest:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: '3.7'
|
|
||||||
- name: Cache pip modules
|
|
||||||
uses: actions/cache@v1
|
|
||||||
with:
|
|
||||||
path: ~/.cache/pip
|
|
||||||
key: esphome-pip-3.7-${{ hashFiles('setup.py') }}
|
|
||||||
restore-keys: |
|
|
||||||
esphome-pip-3.7-
|
|
||||||
- name: Set up environment
|
|
||||||
run: script/setup
|
|
||||||
- name: Install Github Actions annotator
|
|
||||||
run: pip install pytest-github-actions-annotate-failures
|
|
||||||
|
|
||||||
- name: Register problem matchers
|
|
||||||
run: |
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/python.json"
|
|
||||||
- name: Run pytest
|
- name: Run pytest
|
||||||
run: |
|
run: |
|
||||||
pytest \
|
pytest -vv --tb=native tests
|
||||||
-qq \
|
if: ${{ matrix.id == 'pytest' }}
|
||||||
--durations=10 \
|
|
||||||
-o console_output_style=count \
|
|
||||||
tests
|
|
||||||
|
|
96
.github/workflows/docker-lint-build.yml
vendored
96
.github/workflows/docker-lint-build.yml
vendored
|
@ -13,30 +13,88 @@ on:
|
||||||
- '.github/workflows/docker-lint-build.yml'
|
- '.github/workflows/docker-lint-build.yml'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish-docker-lint-iage:
|
deploy-docker:
|
||||||
name: Build docker containers
|
name: Build and publish docker containers
|
||||||
|
if: github.repository == 'esphome/esphome'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
arch: [amd64, armv7, aarch64]
|
||||||
|
build_type: ["lint"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
- name: Set TAG
|
- name: Set TAG
|
||||||
run: |
|
run: |
|
||||||
echo "TAG=1.1" >> $GITHUB_ENV
|
echo "TAG=1.1" >> $GITHUB_ENV
|
||||||
- name: Pull for cache
|
|
||||||
|
- name: Run build
|
||||||
run: |
|
run: |
|
||||||
docker pull "esphome/esphome-lint:latest" || true
|
docker/build.py \
|
||||||
- name: Build
|
--tag "${TAG}" \
|
||||||
run: |
|
--arch "${{ matrix.arch }}" \
|
||||||
docker build \
|
--build-type "${{ matrix.build_type }}" \
|
||||||
--cache-from "esphome/esphome-lint:latest" \
|
build
|
||||||
--file "docker/Dockerfile.lint" \
|
|
||||||
--tag "esphome/esphome-lint:latest" \
|
|
||||||
--tag "esphome/esphome-lint:${TAG}" \
|
|
||||||
.
|
|
||||||
- name: Log in to docker hub
|
- name: Log in to docker hub
|
||||||
env:
|
uses: docker/login-action@v1
|
||||||
DOCKER_USER: ${{ secrets.DOCKER_USER }}
|
with:
|
||||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
username: ${{ secrets.DOCKER_USER }}
|
||||||
run: docker login -u "${DOCKER_USER}" -p "${DOCKER_PASSWORD}"
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
- run: |
|
- name: Log in to the GitHub container registry
|
||||||
docker push "esphome/esphome-lint:${TAG}"
|
uses: docker/login-action@v1
|
||||||
docker push "esphome/esphome-lint:latest"
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Run push
|
||||||
|
run: |
|
||||||
|
docker/build.py \
|
||||||
|
--tag "${TAG}" \
|
||||||
|
--arch "${{ matrix.arch }}" \
|
||||||
|
--build-type "${{ matrix.build_type }}" \
|
||||||
|
push
|
||||||
|
|
||||||
|
deploy-docker-manifest:
|
||||||
|
if: github.repository == 'esphome/esphome'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [deploy-docker]
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
build_type: ["lint"]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
|
- name: Set TAG
|
||||||
|
run: |
|
||||||
|
echo "TAG=1.1" >> $GITHUB_ENV
|
||||||
|
- name: Enable experimental manifest support
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.docker
|
||||||
|
echo "{\"experimental\": \"enabled\"}" > ~/.docker/config.json
|
||||||
|
|
||||||
|
- name: Log in to docker hub
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_USER }}
|
||||||
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
- name: Log in to the GitHub container registry
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Run manifest
|
||||||
|
run: |
|
||||||
|
docker/build.py \
|
||||||
|
--tag "${TAG}" \
|
||||||
|
--build-type "${{ matrix.build_type }}" \
|
||||||
|
manifest
|
||||||
|
|
19
.github/workflows/matchers/pytest.json
vendored
Normal file
19
.github/workflows/matchers/pytest.json
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"problemMatcher": [
|
||||||
|
{
|
||||||
|
"owner": "pytest",
|
||||||
|
"fileLocation": "absolute",
|
||||||
|
"pattern": [
|
||||||
|
{
|
||||||
|
"regexp": "^\\s+File \"(.*)\", line (\\d+), in (.*)$",
|
||||||
|
"file": 1,
|
||||||
|
"line": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"regexp": "^\\s+(.*)$",
|
||||||
|
"message": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
247
.github/workflows/release-dev.yml
vendored
247
.github/workflows/release-dev.yml
vendored
|
@ -1,247 +0,0 @@
|
||||||
name: Publish dev releases to docker hub
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- dev
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
# THE LINT/TEST JOBS ARE COPIED FROM ci.yaml
|
|
||||||
|
|
||||||
lint-clang-format:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
# cpp lint job runs with esphome-lint docker image so that clang-format-*
|
|
||||||
# doesn't have to be installed
|
|
||||||
container: esphome/esphome-lint:1.1
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
# Set up the pio project so that the cpp checks know how files are compiled
|
|
||||||
# (build flags, libraries etc)
|
|
||||||
- name: Set up platformio environment
|
|
||||||
run: pio init --ide atom
|
|
||||||
|
|
||||||
- name: Run clang-format
|
|
||||||
run: script/clang-format -i
|
|
||||||
- name: Suggest changes
|
|
||||||
run: script/ci-suggest-changes
|
|
||||||
|
|
||||||
lint-clang-tidy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
# cpp lint job runs with esphome-lint docker image so that clang-format-*
|
|
||||||
# doesn't have to be installed
|
|
||||||
container: esphome/esphome-lint:1.1
|
|
||||||
# Split clang-tidy check into 4 jobs. Each one will check 1/4th of the .cpp files
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
split: [1, 2, 3, 4]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
# Set up the pio project so that the cpp checks know how files are compiled
|
|
||||||
# (build flags, libraries etc)
|
|
||||||
- name: Set up platformio environment
|
|
||||||
run: pio init --ide atom
|
|
||||||
|
|
||||||
|
|
||||||
- name: Register problem matchers
|
|
||||||
run: |
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/clang-tidy.json"
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/gcc.json"
|
|
||||||
- name: Run clang-tidy
|
|
||||||
run: script/clang-tidy --all-headers --fix --split-num 4 --split-at ${{ matrix.split }}
|
|
||||||
- name: Suggest changes
|
|
||||||
run: script/ci-suggest-changes
|
|
||||||
|
|
||||||
lint-python:
|
|
||||||
# Don't use the esphome-lint docker image because it may contain outdated requirements.
|
|
||||||
# This way, all dependencies are cached via the cache action.
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: '3.7'
|
|
||||||
- name: Cache pip modules
|
|
||||||
uses: actions/cache@v1
|
|
||||||
with:
|
|
||||||
path: ~/.cache/pip
|
|
||||||
key: esphome-pip-3.7-${{ hashFiles('setup.py') }}
|
|
||||||
restore-keys: |
|
|
||||||
esphome-pip-3.7-
|
|
||||||
- name: Set up python environment
|
|
||||||
run: script/setup
|
|
||||||
|
|
||||||
- name: Register problem matchers
|
|
||||||
run: |
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/ci-custom.json"
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/lint-python.json"
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/python.json"
|
|
||||||
- name: Lint Custom
|
|
||||||
run: script/ci-custom.py
|
|
||||||
- name: Lint Python
|
|
||||||
run: script/lint-python
|
|
||||||
- name: Lint CODEOWNERS
|
|
||||||
run: script/build_codeowners.py --check
|
|
||||||
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
test:
|
|
||||||
- test1
|
|
||||||
- test2
|
|
||||||
- test3
|
|
||||||
- test4
|
|
||||||
- test5
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: '3.7'
|
|
||||||
- name: Cache pip modules
|
|
||||||
uses: actions/cache@v1
|
|
||||||
with:
|
|
||||||
path: ~/.cache/pip
|
|
||||||
key: esphome-pip-3.7-${{ hashFiles('setup.py') }}
|
|
||||||
restore-keys: |
|
|
||||||
esphome-pip-3.7-
|
|
||||||
# Use per test platformio cache because tests have different platform versions
|
|
||||||
- name: Cache ~/.platformio
|
|
||||||
uses: actions/cache@v1
|
|
||||||
with:
|
|
||||||
path: ~/.platformio
|
|
||||||
key: test-home-platformio-${{ matrix.test }}-${{ hashFiles('esphome/core/config.py') }}
|
|
||||||
restore-keys: |
|
|
||||||
test-home-platformio-${{ matrix.test }}-
|
|
||||||
- name: Set up environment
|
|
||||||
run: script/setup
|
|
||||||
|
|
||||||
|
|
||||||
- name: Register problem matchers
|
|
||||||
run: |
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/gcc.json"
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/python.json"
|
|
||||||
- run: esphome compile tests/${{ matrix.test }}.yaml
|
|
||||||
|
|
||||||
pytest:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: '3.7'
|
|
||||||
- name: Cache pip modules
|
|
||||||
uses: actions/cache@v1
|
|
||||||
with:
|
|
||||||
path: ~/.cache/pip
|
|
||||||
key: esphome-pip-3.7-${{ hashFiles('setup.py') }}
|
|
||||||
restore-keys: |
|
|
||||||
esphome-pip-3.7-
|
|
||||||
- name: Set up environment
|
|
||||||
run: script/setup
|
|
||||||
- name: Install Github Actions annotator
|
|
||||||
run: pip install pytest-github-actions-annotate-failures
|
|
||||||
|
|
||||||
- name: Register problem matchers
|
|
||||||
run: |
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/python.json"
|
|
||||||
- name: Run pytest
|
|
||||||
run: |
|
|
||||||
pytest \
|
|
||||||
-qq \
|
|
||||||
--durations=10 \
|
|
||||||
-o console_output_style=count \
|
|
||||||
tests
|
|
||||||
|
|
||||||
deploy-docker:
|
|
||||||
name: Build and publish docker containers
|
|
||||||
if: github.repository == 'esphome/esphome'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [lint-clang-format, lint-clang-tidy, lint-python, test, pytest]
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
arch: [amd64, armv7, aarch64]
|
|
||||||
# Hassio dev image doesn't use esphome/esphome-hassio-$arch and uses base directly
|
|
||||||
build_type: ["docker"]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Set TAG
|
|
||||||
run: |
|
|
||||||
TAG="${GITHUB_SHA:0:7}"
|
|
||||||
echo "TAG=${TAG}" >> $GITHUB_ENV
|
|
||||||
- name: Set up env variables
|
|
||||||
run: |
|
|
||||||
base_version="3.4.0"
|
|
||||||
|
|
||||||
if [[ "${{ matrix.build_type }}" == "hassio" ]]; then
|
|
||||||
build_from="esphome/esphome-hassio-base-${{ matrix.arch }}:${base_version}"
|
|
||||||
build_to="esphome/esphome-hassio-${{ matrix.arch }}"
|
|
||||||
dockerfile="docker/Dockerfile.hassio"
|
|
||||||
else
|
|
||||||
build_from="esphome/esphome-base-${{ matrix.arch }}:${base_version}"
|
|
||||||
build_to="esphome/esphome-${{ matrix.arch }}"
|
|
||||||
dockerfile="docker/Dockerfile"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "BUILD_FROM=${build_from}" >> $GITHUB_ENV
|
|
||||||
echo "BUILD_TO=${build_to}" >> $GITHUB_ENV
|
|
||||||
echo "DOCKERFILE=${dockerfile}" >> $GITHUB_ENV
|
|
||||||
- name: Pull for cache
|
|
||||||
run: |
|
|
||||||
docker pull "${BUILD_TO}:dev" || true
|
|
||||||
- name: Register QEMU binfmt
|
|
||||||
run: docker run --rm --privileged multiarch/qemu-user-static:5.2.0-2 --reset -p yes
|
|
||||||
- run: |
|
|
||||||
docker build \
|
|
||||||
--build-arg "BUILD_FROM=${BUILD_FROM}" \
|
|
||||||
--build-arg "BUILD_VERSION=${TAG}" \
|
|
||||||
--tag "${BUILD_TO}:${TAG}" \
|
|
||||||
--tag "${BUILD_TO}:dev" \
|
|
||||||
--cache-from "${BUILD_TO}:dev" \
|
|
||||||
--file "${DOCKERFILE}" \
|
|
||||||
.
|
|
||||||
- name: Log in to docker hub
|
|
||||||
env:
|
|
||||||
DOCKER_USER: ${{ secrets.DOCKER_USER }}
|
|
||||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
run: docker login -u "${DOCKER_USER}" -p "${DOCKER_PASSWORD}"
|
|
||||||
- run: |
|
|
||||||
docker push "${BUILD_TO}:${TAG}"
|
|
||||||
docker push "${BUILD_TO}:dev"
|
|
||||||
|
|
||||||
|
|
||||||
deploy-docker-manifest:
|
|
||||||
if: github.repository == 'esphome/esphome'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [deploy-docker]
|
|
||||||
steps:
|
|
||||||
- name: Enable experimental manifest support
|
|
||||||
run: |
|
|
||||||
mkdir -p ~/.docker
|
|
||||||
echo "{\"experimental\": \"enabled\"}" > ~/.docker/config.json
|
|
||||||
- name: Set TAG
|
|
||||||
run: |
|
|
||||||
TAG="${GITHUB_SHA:0:7}"
|
|
||||||
echo "TAG=${TAG}" >> $GITHUB_ENV
|
|
||||||
- name: Log in to docker hub
|
|
||||||
env:
|
|
||||||
DOCKER_USER: ${{ secrets.DOCKER_USER }}
|
|
||||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
run: docker login -u "${DOCKER_USER}" -p "${DOCKER_PASSWORD}"
|
|
||||||
- name: "Create the manifest"
|
|
||||||
run: |
|
|
||||||
docker manifest create esphome/esphome:${TAG} \
|
|
||||||
esphome/esphome-aarch64:${TAG} \
|
|
||||||
esphome/esphome-amd64:${TAG} \
|
|
||||||
esphome/esphome-armv7:${TAG}
|
|
||||||
docker manifest push esphome/esphome:${TAG}
|
|
||||||
|
|
||||||
docker manifest create esphome/esphome:dev \
|
|
||||||
esphome/esphome-aarch64:${TAG} \
|
|
||||||
esphome/esphome-amd64:${TAG} \
|
|
||||||
esphome/esphome-armv7:${TAG}
|
|
||||||
docker manifest push esphome/esphome:dev
|
|
309
.github/workflows/release.yml
vendored
309
.github/workflows/release.yml
vendored
|
@ -1,164 +1,35 @@
|
||||||
name: Publish Release
|
name: Publish Release
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
release:
|
release:
|
||||||
types: [published]
|
types: [published]
|
||||||
|
schedule:
|
||||||
|
- cron: "0 2 * * *"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# THE LINT/TEST JOBS ARE COPIED FROM ci.yaml
|
init:
|
||||||
|
name: Initialize build
|
||||||
lint-clang-format:
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# cpp lint job runs with esphome-lint docker image so that clang-format-*
|
outputs:
|
||||||
# doesn't have to be installed
|
tag: ${{ steps.tag.outputs.tag }}
|
||||||
container: esphome/esphome-lint:1.1
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
# Set up the pio project so that the cpp checks know how files are compiled
|
- name: Get tag
|
||||||
# (build flags, libraries etc)
|
id: tag
|
||||||
- name: Set up platformio environment
|
|
||||||
run: pio init --ide atom
|
|
||||||
|
|
||||||
- name: Run clang-format
|
|
||||||
run: script/clang-format -i
|
|
||||||
- name: Suggest changes
|
|
||||||
run: script/ci-suggest-changes
|
|
||||||
|
|
||||||
lint-clang-tidy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
# cpp lint job runs with esphome-lint docker image so that clang-format-*
|
|
||||||
# doesn't have to be installed
|
|
||||||
container: esphome/esphome-lint:1.1
|
|
||||||
# Split clang-tidy check into 4 jobs. Each one will check 1/4th of the .cpp files
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
split: [1, 2, 3, 4]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
# Set up the pio project so that the cpp checks know how files are compiled
|
|
||||||
# (build flags, libraries etc)
|
|
||||||
- name: Set up platformio environment
|
|
||||||
run: pio init --ide atom
|
|
||||||
|
|
||||||
|
|
||||||
- name: Register problem matchers
|
|
||||||
run: |
|
run: |
|
||||||
echo "::add-matcher::.github/workflows/matchers/clang-tidy.json"
|
if [[ "$GITHUB_EVENT_NAME" = "release" ]]; then
|
||||||
echo "::add-matcher::.github/workflows/matchers/gcc.json"
|
TAG="${GITHUB_REF#refs/tags/v}"
|
||||||
- name: Run clang-tidy
|
else
|
||||||
run: script/clang-tidy --all-headers --fix --split-num 4 --split-at ${{ matrix.split }}
|
TAG=$(cat esphome/const.py | sed -n -E "s/^__version__\s+=\s+\"(.+)\"$/\1/p")
|
||||||
- name: Suggest changes
|
today="$(date --utc '+%Y%m%d')"
|
||||||
run: script/ci-suggest-changes
|
TAG="${TAG}${today}"
|
||||||
|
fi
|
||||||
lint-python:
|
echo "::set-output name=tag::${TAG}"
|
||||||
# Don't use the esphome-lint docker image because it may contain outdated requirements.
|
|
||||||
# This way, all dependencies are cached via the cache action.
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: '3.7'
|
|
||||||
- name: Cache pip modules
|
|
||||||
uses: actions/cache@v1
|
|
||||||
with:
|
|
||||||
path: ~/.cache/pip
|
|
||||||
key: esphome-pip-3.7-${{ hashFiles('setup.py') }}
|
|
||||||
restore-keys: |
|
|
||||||
esphome-pip-3.7-
|
|
||||||
- name: Set up python environment
|
|
||||||
run: script/setup
|
|
||||||
|
|
||||||
- name: Register problem matchers
|
|
||||||
run: |
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/ci-custom.json"
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/lint-python.json"
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/python.json"
|
|
||||||
- name: Lint Custom
|
|
||||||
run: script/ci-custom.py
|
|
||||||
- name: Lint Python
|
|
||||||
run: script/lint-python
|
|
||||||
- name: Lint CODEOWNERS
|
|
||||||
run: script/build_codeowners.py --check
|
|
||||||
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
test:
|
|
||||||
- test1
|
|
||||||
- test2
|
|
||||||
- test3
|
|
||||||
- test4
|
|
||||||
- test5
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: '3.7'
|
|
||||||
- name: Cache pip modules
|
|
||||||
uses: actions/cache@v1
|
|
||||||
with:
|
|
||||||
path: ~/.cache/pip
|
|
||||||
key: esphome-pip-3.7-${{ hashFiles('setup.py') }}
|
|
||||||
restore-keys: |
|
|
||||||
esphome-pip-3.7-
|
|
||||||
# Use per test platformio cache because tests have different platform versions
|
|
||||||
- name: Cache ~/.platformio
|
|
||||||
uses: actions/cache@v1
|
|
||||||
with:
|
|
||||||
path: ~/.platformio
|
|
||||||
key: test-home-platformio-${{ matrix.test }}-${{ hashFiles('esphome/core/config.py') }}
|
|
||||||
restore-keys: |
|
|
||||||
test-home-platformio-${{ matrix.test }}-
|
|
||||||
- name: Set up environment
|
|
||||||
run: script/setup
|
|
||||||
|
|
||||||
- name: Register problem matchers
|
|
||||||
run: |
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/gcc.json"
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/python.json"
|
|
||||||
- run: esphome compile tests/${{ matrix.test }}.yaml
|
|
||||||
|
|
||||||
pytest:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: '3.7'
|
|
||||||
- name: Cache pip modules
|
|
||||||
uses: actions/cache@v1
|
|
||||||
with:
|
|
||||||
path: ~/.cache/pip
|
|
||||||
key: esphome-pip-3.7-${{ hashFiles('setup.py') }}
|
|
||||||
restore-keys: |
|
|
||||||
esphome-pip-3.7-
|
|
||||||
- name: Set up environment
|
|
||||||
run: script/setup
|
|
||||||
- name: Install Github Actions annotator
|
|
||||||
run: pip install pytest-github-actions-annotate-failures
|
|
||||||
|
|
||||||
- name: Register problem matchers
|
|
||||||
run: |
|
|
||||||
echo "::add-matcher::.github/workflows/matchers/python.json"
|
|
||||||
- name: Run pytest
|
|
||||||
run: |
|
|
||||||
pytest \
|
|
||||||
-qq \
|
|
||||||
--durations=10 \
|
|
||||||
-o console_output_style=count \
|
|
||||||
tests
|
|
||||||
|
|
||||||
deploy-pypi:
|
deploy-pypi:
|
||||||
name: Build and publish to PyPi
|
name: Build and publish to PyPi
|
||||||
if: github.repository == 'esphome/esphome'
|
if: github.repository == 'esphome/esphome' && github.event_name == 'release'
|
||||||
needs: [lint-clang-format, lint-clang-tidy, lint-python, test, pytest]
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
@ -182,119 +53,85 @@ jobs:
|
||||||
name: Build and publish docker containers
|
name: Build and publish docker containers
|
||||||
if: github.repository == 'esphome/esphome'
|
if: github.repository == 'esphome/esphome'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [lint-clang-format, lint-clang-tidy, lint-python, test, pytest]
|
needs: [init]
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
arch: [amd64, armv7, aarch64]
|
arch: [amd64, armv7, aarch64]
|
||||||
build_type: ["hassio", "docker"]
|
build_type: ["ha-addon", "docker"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set TAG
|
- name: Set up Python
|
||||||
run: |
|
uses: actions/setup-python@v2
|
||||||
TAG="${GITHUB_REF#refs/tags/v}"
|
with:
|
||||||
echo "TAG=${TAG}" >> $GITHUB_ENV
|
python-version: '3.9'
|
||||||
- name: Set up env variables
|
|
||||||
run: |
|
|
||||||
base_version="3.4.0"
|
|
||||||
|
|
||||||
if [[ "${{ matrix.build_type }}" == "hassio" ]]; then
|
- name: Run build
|
||||||
build_from="esphome/esphome-hassio-base-${{ matrix.arch }}:${base_version}"
|
|
||||||
build_to="esphome/esphome-hassio-${{ matrix.arch }}"
|
|
||||||
dockerfile="docker/Dockerfile.hassio"
|
|
||||||
else
|
|
||||||
build_from="esphome/esphome-base-${{ matrix.arch }}:${base_version}"
|
|
||||||
build_to="esphome/esphome-${{ matrix.arch }}"
|
|
||||||
dockerfile="docker/Dockerfile"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${{ github.event.release.prerelease }}" == "true" ]]; then
|
|
||||||
cache_tag="beta"
|
|
||||||
else
|
|
||||||
cache_tag="latest"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set env variables so these values don't need to be calculated again
|
|
||||||
echo "BUILD_FROM=${build_from}" >> $GITHUB_ENV
|
|
||||||
echo "BUILD_TO=${build_to}" >> $GITHUB_ENV
|
|
||||||
echo "DOCKERFILE=${dockerfile}" >> $GITHUB_ENV
|
|
||||||
echo "CACHE_TAG=${cache_tag}" >> $GITHUB_ENV
|
|
||||||
- name: Pull for cache
|
|
||||||
run: |
|
run: |
|
||||||
docker pull "${BUILD_TO}:${CACHE_TAG}" || true
|
docker/build.py \
|
||||||
- name: Register QEMU binfmt
|
--tag "${{ needs.init.outputs.tag }}" \
|
||||||
run: docker run --rm --privileged multiarch/qemu-user-static:5.2.0-2 --reset -p yes
|
--arch "${{ matrix.arch }}" \
|
||||||
- run: |
|
--build-type "${{ matrix.build_type }}" \
|
||||||
docker build \
|
build
|
||||||
--build-arg "BUILD_FROM=${BUILD_FROM}" \
|
|
||||||
--build-arg "BUILD_VERSION=${TAG}" \
|
|
||||||
--tag "${BUILD_TO}:${TAG}" \
|
|
||||||
--cache-from "${BUILD_TO}:${CACHE_TAG}" \
|
|
||||||
--file "${DOCKERFILE}" \
|
|
||||||
.
|
|
||||||
- name: Log in to docker hub
|
- name: Log in to docker hub
|
||||||
env:
|
uses: docker/login-action@v1
|
||||||
DOCKER_USER: ${{ secrets.DOCKER_USER }}
|
with:
|
||||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
username: ${{ secrets.DOCKER_USER }}
|
||||||
run: docker login -u "${DOCKER_USER}" -p "${DOCKER_PASSWORD}"
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
- run: docker push "${BUILD_TO}:${TAG}"
|
- name: Log in to the GitHub container registry
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
# Always publish to beta tag (also full releases)
|
- name: Run push
|
||||||
- name: Publish docker beta tag
|
|
||||||
run: |
|
run: |
|
||||||
docker tag "${BUILD_TO}:${TAG}" "${BUILD_TO}:beta"
|
docker/build.py \
|
||||||
docker push "${BUILD_TO}:beta"
|
--tag "${{ needs.init.outputs.tag }}" \
|
||||||
|
--arch "${{ matrix.arch }}" \
|
||||||
- if: ${{ !github.event.release.prerelease }}
|
--build-type "${{ matrix.build_type }}" \
|
||||||
name: Publish docker latest tag
|
push
|
||||||
run: |
|
|
||||||
docker tag "${BUILD_TO}:${TAG}" "${BUILD_TO}:latest"
|
|
||||||
docker push "${BUILD_TO}:latest"
|
|
||||||
|
|
||||||
deploy-docker-manifest:
|
deploy-docker-manifest:
|
||||||
if: github.repository == 'esphome/esphome'
|
if: github.repository == 'esphome/esphome'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [deploy-docker]
|
needs: [init, deploy-docker]
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
build_type: ["ha-addon", "docker"]
|
||||||
steps:
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
- name: Enable experimental manifest support
|
- name: Enable experimental manifest support
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ~/.docker
|
mkdir -p ~/.docker
|
||||||
echo "{\"experimental\": \"enabled\"}" > ~/.docker/config.json
|
echo "{\"experimental\": \"enabled\"}" > ~/.docker/config.json
|
||||||
- name: Set TAG
|
|
||||||
run: |
|
|
||||||
TAG="${GITHUB_REF#refs/tags/v}"
|
|
||||||
echo "TAG=${TAG}" >> $GITHUB_ENV
|
|
||||||
- name: Log in to docker hub
|
- name: Log in to docker hub
|
||||||
env:
|
uses: docker/login-action@v1
|
||||||
DOCKER_USER: ${{ secrets.DOCKER_USER }}
|
with:
|
||||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
username: ${{ secrets.DOCKER_USER }}
|
||||||
run: docker login -u "${DOCKER_USER}" -p "${DOCKER_PASSWORD}"
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
- name: "Create the manifest"
|
- name: Log in to the GitHub container registry
|
||||||
run: |
|
uses: docker/login-action@v1
|
||||||
docker manifest create esphome/esphome:${TAG} \
|
with:
|
||||||
esphome/esphome-aarch64:${TAG} \
|
registry: ghcr.io
|
||||||
esphome/esphome-amd64:${TAG} \
|
username: ${{ github.actor }}
|
||||||
esphome/esphome-armv7:${TAG}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
docker manifest push esphome/esphome:${TAG}
|
|
||||||
|
|
||||||
- name: Publish docker beta tag
|
- name: Run manifest
|
||||||
run: |
|
run: |
|
||||||
docker manifest create esphome/esphome:beta \
|
docker/build.py \
|
||||||
esphome/esphome-aarch64:${TAG} \
|
--tag "${{ needs.init.outputs.tag }}" \
|
||||||
esphome/esphome-amd64:${TAG} \
|
--build-type "${{ matrix.build_type }}" \
|
||||||
esphome/esphome-armv7:${TAG}
|
manifest
|
||||||
docker manifest push esphome/esphome:beta
|
|
||||||
|
|
||||||
- name: Publish docker latest tag
|
|
||||||
if: ${{ !github.event.release.prerelease }}
|
|
||||||
run: |
|
|
||||||
docker manifest create esphome/esphome:latest \
|
|
||||||
esphome/esphome-aarch64:${TAG} \
|
|
||||||
esphome/esphome-amd64:${TAG} \
|
|
||||||
esphome/esphome-armv7:${TAG}
|
|
||||||
docker manifest push esphome/esphome:latest
|
|
||||||
|
|
||||||
deploy-hassio-repo:
|
deploy-hassio-repo:
|
||||||
if: github.repository == 'esphome/esphome'
|
if: github.repository == 'esphome/esphome' && github.event_name == 'release'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [deploy-docker]
|
needs: [deploy-docker]
|
||||||
steps:
|
steps:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BUILD_FROM=esphome/esphome-base-amd64:3.4.0
|
ARG BUILD_FROM=esphome/esphome-base:latest
|
||||||
FROM ${BUILD_FROM}
|
FROM ${BUILD_FROM}
|
||||||
|
|
||||||
# First install requirements to leverage caching when requirements don't change
|
# First install requirements to leverage caching when requirements don't change
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG BUILD_FROM
|
ARG BUILD_FROM=esphome/esphome-hassio-base:latest
|
||||||
FROM ${BUILD_FROM}
|
FROM ${BUILD_FROM}
|
||||||
|
|
||||||
# First install requirements to leverage caching when requirements don't change
|
# First install requirements to leverage caching when requirements don't change
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
FROM esphome/esphome-lint-base:3.4.0
|
ARG BUILD_FROM=esphome/esphome-lint-base:latest
|
||||||
|
FROM ${BUILD_FROM}
|
||||||
|
|
||||||
COPY requirements.txt requirements_optional.txt requirements_test.txt docker/platformio_install_deps.py platformio.ini /
|
COPY requirements.txt requirements_optional.txt requirements_test.txt docker/platformio_install_deps.py platformio.ini /
|
||||||
RUN \
|
RUN \
|
||||||
|
|
177
docker/build.py
Executable file
177
docker/build.py
Executable file
|
@ -0,0 +1,177 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
from dataclasses import dataclass
|
||||||
|
import subprocess
|
||||||
|
import argparse
|
||||||
|
import platform
|
||||||
|
import shlex
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
CHANNEL_DEV = 'dev'
|
||||||
|
CHANNEL_BETA = 'beta'
|
||||||
|
CHANNEL_RELEASE = 'release'
|
||||||
|
CHANNELS = [CHANNEL_DEV, CHANNEL_BETA, CHANNEL_RELEASE]
|
||||||
|
|
||||||
|
ARCH_AMD64 = 'amd64'
|
||||||
|
ARCH_ARMV7 = 'armv7'
|
||||||
|
ARCH_AARCH64 = 'aarch64'
|
||||||
|
ARCHS = [ARCH_AMD64, ARCH_ARMV7, ARCH_AARCH64]
|
||||||
|
|
||||||
|
TYPE_DOCKER = 'docker'
|
||||||
|
TYPE_HA_ADDON = 'ha-addon'
|
||||||
|
TYPE_LINT = 'lint'
|
||||||
|
TYPES = [TYPE_DOCKER, TYPE_HA_ADDON, TYPE_LINT]
|
||||||
|
|
||||||
|
|
||||||
|
BASE_VERSION = "3.6.0"
|
||||||
|
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--tag", type=str, required=True, help="The main docker tag to push to. If a version number also adds latest and/or beta tag")
|
||||||
|
parser.add_argument("--arch", choices=ARCHS, required=False, help="The architecture to build for")
|
||||||
|
parser.add_argument("--build-type", choices=TYPES, required=True, help="The type of build to run")
|
||||||
|
parser.add_argument("--dry-run", action="store_true", help="Don't run any commands, just print them")
|
||||||
|
subparsers = parser.add_subparsers(help="Action to perform", dest="command", required=True)
|
||||||
|
build_parser = subparsers.add_parser("build", help="Build the image")
|
||||||
|
push_parser = subparsers.add_parser("push", help="Tag the already built image and push it to docker hub")
|
||||||
|
manifest_parser = subparsers.add_parser("manifest", help="Create a manifest from already pushed images")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# only lists some possibilities, doesn't have to be perfect
|
||||||
|
# https://stackoverflow.com/a/45125525
|
||||||
|
UNAME_TO_ARCH = {
|
||||||
|
"x86_64": ARCH_AMD64,
|
||||||
|
"aarch64": ARCH_AARCH64,
|
||||||
|
"aarch64_be": ARCH_AARCH64,
|
||||||
|
"arm": ARCH_ARMV7,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class DockerParams:
|
||||||
|
build_from: str
|
||||||
|
build_to: str
|
||||||
|
manifest_to: str
|
||||||
|
dockerfile: str
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def for_type_arch(cls, build_type, arch):
|
||||||
|
prefix = {
|
||||||
|
TYPE_DOCKER: "esphome/esphome",
|
||||||
|
TYPE_HA_ADDON: "esphome/esphome-hassio",
|
||||||
|
TYPE_LINT: "esphome/esphome-lint"
|
||||||
|
}[build_type]
|
||||||
|
build_from = f"ghcr.io/{prefix}-base-{arch}:{BASE_VERSION}"
|
||||||
|
build_to = f"{prefix}-{arch}"
|
||||||
|
dockerfile = {
|
||||||
|
TYPE_DOCKER: "docker/Dockerfile",
|
||||||
|
TYPE_HA_ADDON: "docker/Dockerfile.hassio",
|
||||||
|
TYPE_LINT: "docker/Dockerfile.lint",
|
||||||
|
}[build_type]
|
||||||
|
return cls(
|
||||||
|
build_from=build_from,
|
||||||
|
build_to=build_to,
|
||||||
|
manifest_to=prefix,
|
||||||
|
dockerfile=dockerfile
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
def run_command(*cmd, ignore_error: bool = False):
|
||||||
|
print(f"$ {shlex.join(list(cmd))}")
|
||||||
|
if not args.dry_run:
|
||||||
|
rc = subprocess.call(list(cmd))
|
||||||
|
if rc != 0 and not ignore_error:
|
||||||
|
print("Command failed")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# detect channel from tag
|
||||||
|
match = re.match(r'\d+\.\d+(?:\.\d+)?(b\d+)?', args.tag)
|
||||||
|
if match is None:
|
||||||
|
channel = CHANNEL_DEV
|
||||||
|
elif match.group(1) is None:
|
||||||
|
channel = CHANNEL_RELEASE
|
||||||
|
else:
|
||||||
|
channel = CHANNEL_BETA
|
||||||
|
|
||||||
|
tags_to_push = [args.tag]
|
||||||
|
if channel == CHANNEL_DEV:
|
||||||
|
tags_to_push.append("dev")
|
||||||
|
elif channel == CHANNEL_BETA:
|
||||||
|
tags_to_push.append("beta")
|
||||||
|
elif channel == CHANNEL_RELEASE:
|
||||||
|
# Additionally push to beta
|
||||||
|
tags_to_push.append("beta")
|
||||||
|
tags_to_push.append("latest")
|
||||||
|
|
||||||
|
if args.command == "build":
|
||||||
|
# 1. pull cache image
|
||||||
|
params = DockerParams.for_type_arch(args.build_type, args.arch)
|
||||||
|
cache_tag = {
|
||||||
|
CHANNEL_DEV: "dev",
|
||||||
|
CHANNEL_BETA: "beta",
|
||||||
|
CHANNEL_RELEASE: "latest",
|
||||||
|
}[channel]
|
||||||
|
cache_img = f"ghcr.io/{params.build_to}:{cache_tag}"
|
||||||
|
run_command("docker", "pull", cache_img, ignore_error=True)
|
||||||
|
|
||||||
|
# 2. register QEMU binfmt (if not host arch)
|
||||||
|
is_native = UNAME_TO_ARCH.get(platform.machine()) == args.arch
|
||||||
|
if not is_native:
|
||||||
|
run_command(
|
||||||
|
"docker", "run", "--rm", "--privileged", "multiarch/qemu-user-static:5.2.0-2",
|
||||||
|
"--reset", "-p", "yes"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 3. build
|
||||||
|
run_command(
|
||||||
|
"docker", "build",
|
||||||
|
"--build-arg", f"BUILD_FROM={params.build_from}",
|
||||||
|
"--build-arg", f"BUILD_VERSION={args.tag}",
|
||||||
|
"--tag", f"{params.build_to}:{args.tag}",
|
||||||
|
"--cache-from", cache_img,
|
||||||
|
"--file", params.dockerfile,
|
||||||
|
"."
|
||||||
|
)
|
||||||
|
elif args.command == "push":
|
||||||
|
params = DockerParams.for_type_arch(args.build_type, args.arch)
|
||||||
|
imgs = [f"{params.build_to}:{tag}" for tag in tags_to_push]
|
||||||
|
imgs += [f"ghcr.io/{params.build_to}:{tag}" for tag in tags_to_push]
|
||||||
|
src = imgs[0]
|
||||||
|
# 1. tag images
|
||||||
|
for img in imgs[1:]:
|
||||||
|
run_command(
|
||||||
|
"docker", "tag", src, img
|
||||||
|
)
|
||||||
|
# 2. push images
|
||||||
|
for img in imgs:
|
||||||
|
run_command(
|
||||||
|
"docker", "push", img
|
||||||
|
)
|
||||||
|
elif args.command == "manifest":
|
||||||
|
manifest = DockerParams.for_type_arch(args.build_type, ARCH_AMD64).manifest_to
|
||||||
|
|
||||||
|
targets = [f"{manifest}:{tag}" for tag in tags_to_push]
|
||||||
|
targets += [f"ghcr.io/{manifest}:{tag}" for tag in tags_to_push]
|
||||||
|
# 1. Create manifests
|
||||||
|
for target in targets:
|
||||||
|
cmd = ["docker", "manifest", "create", target]
|
||||||
|
for arch in ARCHS:
|
||||||
|
src = f"{DockerParams.for_type_arch(args.build_type, arch).build_to}:{args.tag}"
|
||||||
|
if target.startswith("ghcr.io"):
|
||||||
|
src = f"ghcr.io/{src}"
|
||||||
|
cmd.append(src)
|
||||||
|
run_command(*cmd)
|
||||||
|
# 2. Push manifests
|
||||||
|
for target in targets:
|
||||||
|
run_command(
|
||||||
|
"docker", "manifest", "push", target
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -1,10 +1,6 @@
|
||||||
"""Constants used by esphome."""
|
"""Constants used by esphome."""
|
||||||
|
|
||||||
MAJOR_VERSION = 1
|
__version__ = "1.21.0-dev"
|
||||||
MINOR_VERSION = 21
|
|
||||||
PATCH_VERSION = "0-dev"
|
|
||||||
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
|
||||||
__version__ = f"{__short_version__}.{PATCH_VERSION}"
|
|
||||||
|
|
||||||
ESP_PLATFORM_ESP32 = "ESP32"
|
ESP_PLATFORM_ESP32 = "ESP32"
|
||||||
ESP_PLATFORM_ESP8266 = "ESP8266"
|
ESP_PLATFORM_ESP8266 = "ESP8266"
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def sub(path, pattern, repl, expected_count=1):
|
|
||||||
with open(path) as fh:
|
|
||||||
content = fh.read()
|
|
||||||
content, count = re.subn(pattern, repl, content, flags=re.MULTILINE)
|
|
||||||
if expected_count is not None:
|
|
||||||
assert count == expected_count, f"Pattern {pattern} replacement failed!"
|
|
||||||
with open(path, "wt") as fh:
|
|
||||||
fh.write(content)
|
|
||||||
|
|
||||||
|
|
||||||
def write_version(version: str):
|
|
||||||
for p in [
|
|
||||||
".github/workflows/ci-docker.yml",
|
|
||||||
".github/workflows/release-dev.yml",
|
|
||||||
".github/workflows/release.yml",
|
|
||||||
]:
|
|
||||||
sub(p, r'base_version=".*"', f'base_version="{version}"')
|
|
||||||
|
|
||||||
sub(
|
|
||||||
"docker/Dockerfile",
|
|
||||||
r"ARG BUILD_FROM=esphome/esphome-base-amd64:.*",
|
|
||||||
f"ARG BUILD_FROM=esphome/esphome-base-amd64:{version}",
|
|
||||||
)
|
|
||||||
sub(
|
|
||||||
"docker/Dockerfile.lint",
|
|
||||||
r"FROM esphome/esphome-lint-base:.*",
|
|
||||||
f"FROM esphome/esphome-lint-base:{version}",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument("new_version", type=str)
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
version = args.new_version
|
|
||||||
print(f"Bumping to {version}")
|
|
||||||
write_version(version)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
sys.exit(main() or 0)
|
|
|
@ -50,16 +50,10 @@ def sub(path, pattern, repl, expected_count=1):
|
||||||
|
|
||||||
|
|
||||||
def write_version(version: Version):
|
def write_version(version: Version):
|
||||||
sub(
|
|
||||||
"esphome/const.py", r"^MAJOR_VERSION = \d+$", f"MAJOR_VERSION = {version.major}"
|
|
||||||
)
|
|
||||||
sub(
|
|
||||||
"esphome/const.py", r"^MINOR_VERSION = \d+$", f"MINOR_VERSION = {version.minor}"
|
|
||||||
)
|
|
||||||
sub(
|
sub(
|
||||||
"esphome/const.py",
|
"esphome/const.py",
|
||||||
r"^PATCH_VERSION = .*$",
|
r"^__version__ = .*$",
|
||||||
f'PATCH_VERSION = "{version.full_patch}"',
|
f'__version__ = "{version}"',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue