Skip to content

Commit 8f83cf2

Browse files
authored
Adding Release Workflow and some other tweaks (#96)
1 parent 3c4e215 commit 8f83cf2

14 files changed

+438
-4
lines changed

.devcontainer/devcontainer.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@
66
"extensions": [
77
"esphome.esphome-vscode",
88
"redhat.vscode-yaml",
9-
"ms-python.python"
9+
"ms-python.python",
10+
"SanjulaGanepola.github-local-actions",
11+
"github.vscode-github-actions"
1012
]
1113
}
1214
},
13-
"features": {},
15+
"features": {
16+
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
17+
},
18+
"postCreateCommand": ".devcontainer/postCreateCommand.sh",
1419
"remoteUser": "root",
1520
"workspaceFolder": "/workspaces/esphome_components"
1621
}

.devcontainer/postCreateCommand.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
echo "Starting post-create setup..."
6+
7+
# Install act for local GitHub Actions testing
8+
echo "Installing act..."
9+
# Options:
10+
# -b /usr/local/bin : Install to /usr/local/bin (globally available)
11+
# -d : Enable debug logging
12+
# -f : Force installation
13+
# [tag] : Specific version (e.g., v0.2.26)
14+
curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/nektos/act/master/install.sh | bash -s -- -b /usr/local/bin
15+
16+
# Make act available in PATH
17+
echo "Making act available in PATH..."
18+
if [ -f "/usr/local/bin/act" ]; then
19+
echo "act successfully installed at /usr/local/bin/act"
20+
else
21+
echo "Warning: act installation may have failed"
22+
fi
23+
24+
# Verify installation
25+
echo "Verifying act installation..."
26+
act --version || echo "act not found in PATH"
27+
28+
echo "Post-create setup completed!"

.github/workflows/ci.yml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- '*.yaml'
7+
- '.github/workflows/ci.yml'
8+
# push:
9+
# branches:
10+
# - main
11+
# - 'releases/**'
12+
13+
# schedule:
14+
# - cron: '0 0 * * *'
15+
16+
concurrency:
17+
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
18+
cancel-in-progress: true
19+
20+
jobs:
21+
ci:
22+
name: Building ${{ matrix.file }} / ${{ matrix.esphome-version }}
23+
runs-on: ubuntu-latest
24+
strategy:
25+
fail-fast: false
26+
max-parallel: 3
27+
matrix:
28+
#### Modify below here to match your project ####
29+
file:
30+
- buderus-km271
31+
- buderus-km271_en
32+
- buderus-km271_en_noimprov
33+
- buderus-km271-hc2-rw
34+
- buderus-km271-writable-espidf
35+
- buderus-km271-writable-8MB
36+
#### Modify above here to match your project ####
37+
38+
esphome-version:
39+
- 2025.7.2
40+
#- stable
41+
42+
steps:
43+
- name: Checkout source code
44+
uses: actions/checkout@v4.2.2
45+
with:
46+
fetch-depth: 0
47+
- name: Create temporary secrets.yaml
48+
run: |
49+
cat > secrets.yaml << EOF
50+
# Temporary secrets for CI builds
51+
wifi_ssid: "CI_TEST_NETWORK"
52+
wifi_password: "ci_test_password_123"
53+
wifi_pass: "ci_test_password_123"
54+
ap_password: "ci_ap_password_123"
55+
ota_password: "ci_ota_password_123"
56+
api_encryption_key: "$(openssl rand -base64 32)"
57+
EOF
58+
echo "Created temporary secrets.yaml for CI build"
59+
- name: ESPHome ${{ matrix.esphome-version }}
60+
uses: esphome/build-action@v7.0.0
61+
with:
62+
yaml-file: ${{ matrix.file }}.yaml
63+
version: ${{ matrix.esphome-version }}
64+
- name: ESPHome ${{ matrix.esphome-version }} Factory
65+
uses: esphome/build-action@v7.0.0
66+
with:
67+
yaml-file: ${{ matrix.file }}.factory.yaml
68+
version: ${{ matrix.esphome-version }}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: Publish Firmware
2+
3+
on:
4+
release:
5+
types: [published]
6+
workflow_run:
7+
workflows:
8+
- "Semantic Release"
9+
types:
10+
- completed
11+
12+
permissions:
13+
contents: write
14+
15+
jobs:
16+
set-release-version:
17+
name: Extract Release Version
18+
runs-on: ubuntu-latest
19+
# Only run if workflow_run was successful or if it's a direct release trigger
20+
if: github.event_name == 'release' || github.event.workflow_run.conclusion == 'success'
21+
outputs:
22+
release_version: ${{ steps.set-version.outputs.release_version }}
23+
steps:
24+
- name: Checkout code
25+
uses: actions/checkout@v4
26+
with:
27+
fetch-depth: 0
28+
29+
- name: Extract release-version
30+
id: set-version
31+
run: |
32+
if [ "${{ github.event.release.tag_name }}" != "" ]; then
33+
# Direct release trigger
34+
echo "Release version from event: ${{ github.event.release.tag_name }}"
35+
echo "release_version=${{ github.event.release.tag_name }}" | tee -a $GITHUB_OUTPUT
36+
else
37+
# Workflow run trigger - get the latest release tag
38+
echo "Fetching latest release tag..."
39+
LATEST_TAG=$(git describe --tags --abbrev=0)
40+
echo "release_version=${LATEST_TAG}" | tee -a $GITHUB_OUTPUT
41+
fi
42+
43+
build-firmware:
44+
name: Build Firmware
45+
needs: set-release-version
46+
uses: esphome/workflows/.github/workflows/build.yml@2025.4.0
47+
with:
48+
files: |
49+
buderus-km271.yaml
50+
buderus-km271_en.yaml
51+
buderus-km271_en_noimprov.yaml
52+
buderus-km271-hc2-rw.yaml
53+
buderus-km271-writable-espidf.yaml
54+
buderus-km271-writable-8MB.yaml
55+
esphome-version: 2025.7.2
56+
combined-name: buderus-km271
57+
release-version: ${{ needs.set-release-version.outputs.release_version }}
58+
59+
upload-to-release:
60+
name: Upload to Release
61+
needs:
62+
- build-firmware
63+
- set-release-version
64+
uses: esphome/workflows/.github/workflows/upload-to-gh-release.yml@2025.4.0
65+
with:
66+
version: ${{ needs.set-release-version.outputs.release_version }}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
name: Semantic Release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
release:
13+
name: Create SemVer Release
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
with:
20+
fetch-depth: 0 # wichtig für vollständige git history
21+
22+
- name: Get latest version tag
23+
id: get_latest
24+
run: |
25+
git fetch --tags
26+
latest=$(git tag --list 'v*' --sort=-v:refname | head -n1 || echo "v0.0.0")
27+
echo "latest=$latest" >> $GITHUB_OUTPUT
28+
29+
- name: Generate new version
30+
id: semver
31+
uses: paulhatch/semantic-version@v5.4.0
32+
with:
33+
tag_prefix: "v"
34+
major_pattern: "/(feat|fix|refactor)!:/"
35+
minor_pattern: "/^feat:/"
36+
version_format: "${major}.${minor}.${patch}"
37+
search_commit_body: true
38+
debug: true
39+
40+
- name: Check if new release is needed
41+
id: check
42+
run: |
43+
if [ "v${{ steps.semver.outputs.version }}" == "${{ steps.get_latest.outputs.latest }}" ]; then
44+
echo "No new version needed."
45+
echo "release=false" >> $GITHUB_OUTPUT
46+
else
47+
echo "New version will be: ${{ steps.semver.outputs.version }}"
48+
echo "release=true" >> $GITHUB_OUTPUT
49+
fi
50+
51+
- name: Generate changelog
52+
if: steps.check.outputs.release == 'true'
53+
id: changelog
54+
run: |
55+
NEW_TAG="v${{ steps.semver.outputs.version }}"
56+
OLD_TAG="${{ steps.get_latest.outputs.latest }}"
57+
58+
echo "release_notes<<EOF" >> $GITHUB_OUTPUT
59+
echo "## Changelog" >> $GITHUB_OUTPUT
60+
61+
FEATS=$(git log ${OLD_TAG}..HEAD --grep="^feat" --pretty=format:"- %s" || true)
62+
FIXES=$(git log ${OLD_TAG}..HEAD --grep="^fix" --pretty=format:"- %s" || true)
63+
BREAKS=$(git log ${OLD_TAG}..HEAD --grep="!:" --pretty=format:"- %s" || true)
64+
65+
ANY_OUTPUT=false
66+
67+
if [ -n "$FEATS" ]; then
68+
echo -e "\n### ✨ Features" >> $GITHUB_OUTPUT
69+
echo "$FEATS" >> $GITHUB_OUTPUT
70+
ANY_OUTPUT=true
71+
fi
72+
73+
if [ -n "$FIXES" ]; then
74+
echo -e "\n### 🐛 Fixes" >> $GITHUB_OUTPUT
75+
echo "$FIXES" >> $GITHUB_OUTPUT
76+
ANY_OUTPUT=true
77+
fi
78+
79+
if [ -n "$BREAKS" ]; then
80+
echo -e "\n### 💥 Breaking Changes" >> $GITHUB_OUTPUT
81+
echo "$BREAKS" >> $GITHUB_OUTPUT
82+
ANY_OUTPUT=true
83+
fi
84+
85+
if [ "$ANY_OUTPUT" = false ]; then
86+
echo -e "\n### 📝 Commits" >> $GITHUB_OUTPUT
87+
git log ${OLD_TAG}..HEAD --pretty=format:"- %s" >> $GITHUB_OUTPUT
88+
fi
89+
90+
echo -e "\n---\n**Full Changelog:** [${OLD_TAG}...${NEW_TAG}](https://github.com/${{ github.repository }}/compare/${OLD_TAG}...${NEW_TAG})" >> $GITHUB_OUTPUT
91+
echo "EOF" >> $GITHUB_OUTPUT
92+
93+
- name: Create GitHub Release
94+
if: steps.check.outputs.release == 'true'
95+
uses: softprops/action-gh-release@v2
96+
with:
97+
tag_name: v${{ steps.semver.outputs.version }}
98+
name: Release v${{ steps.semver.outputs.version }}
99+
body: ${{ steps.changelog.outputs.release_notes }}

.vscode/extensions.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"recommendations": [
3+
"github.vscode-github-actions",
4+
"sanjulaganepola.github-local-actions"
5+
]
6+
}

buderus-km271-hc2-rw.factory.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
packages:
2+
# Include all of the core configuration
3+
core: !include buderus-km271-hc2-rw.yaml
4+
5+
esphome:
6+
# This will allow for project identification,
7+
# configuration and updates.
8+
project:
9+
#name: esphome.project-template
10+
name: esphome.km271-wifi
11+
version: dev # This will be replaced by the github workflows with the `release` version
12+
13+
# This should point to the public location of the yaml file that will be adopted.
14+
# In this case it is the core yaml file that does not contain the extra things
15+
# that are provided by this factory yaml file as the user does not need these once adopted.
16+
dashboard_import:
17+
package_import_url: github://the78mole/ESPhome-KM271-WiFi/blob/main/buderus-km271_en_8MB.yaml
18+
19+
# Sets up the improv via serial client for Wi-Fi provisioning.
20+
# Handy if your device has a usb port for the user to add credentials when they first get it.
21+
improv_serial:
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
packages:
2+
# Include all of the core configuration
3+
core: !include buderus-km271-writable-8MB.yaml
4+
5+
esphome:
6+
# This will allow for project identification,
7+
# configuration and updates.
8+
project:
9+
#name: esphome.project-template
10+
name: esphome.km271-wifi
11+
version: dev # This will be replaced by the github workflows with the `release` version
12+
13+
# This should point to the public location of the yaml file that will be adopted.
14+
# In this case it is the core yaml file that does not contain the extra things
15+
# that are provided by this factory yaml file as the user does not need these once adopted.
16+
dashboard_import:
17+
package_import_url: github://the78mole/ESPhome-KM271-WiFi/blob/main/buderus-km271_en_8MB.yaml
18+
19+
# Sets up the improv via serial client for Wi-Fi provisioning.
20+
# Handy if your device has a usb port for the user to add credentials when they first get it.
21+
improv_serial:
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
packages:
2+
# Include all of the core configuration
3+
core: !include buderus-km271-writable-espidf.yaml
4+
5+
esphome:
6+
# This will allow for project identification,
7+
# configuration and updates.
8+
project:
9+
#name: esphome.project-template
10+
name: esphome.km271-wifi
11+
version: dev # This will be replaced by the github workflows with the `release` version
12+
13+
# This should point to the public location of the yaml file that will be adopted.
14+
# In this case it is the core yaml file that does not contain the extra things
15+
# that are provided by this factory yaml file as the user does not need these once adopted.
16+
dashboard_import:
17+
package_import_url: github://the78mole/ESPhome-KM271-WiFi/blob/main/buderus-km271_en_8MB.yaml
18+
19+
# Sets up the improv via serial client for Wi-Fi provisioning.
20+
# Handy if your device has a usb port for the user to add credentials when they first get it.
21+
improv_serial:

0 commit comments

Comments
 (0)