Skip to content

Add native Home Assistant (HACS) integration #19

Add native Home Assistant (HACS) integration

Add native Home Assistant (HACS) integration #19

Workflow file for this run

name: Validate Integration
on:
push:
branches: ["main", "develop"]
pull_request:
schedule:
- cron: "0 6 * * *"
permissions: {}
jobs:
hacs:
name: HACS validation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: HACS Action
uses: hacs/action@main
with:
category: integration
# `brands` (home-assistant/brands icon) and `topics` (GitHub repo
# topics) are repo-admin/external prerequisites tracked separately;
# ignore them so this job reflects the integration's own validity.
# Add topics (home-assistant, hacs, marstek, energy) + the brands PR
# before submitting to the HACS default store.
ignore: brands topics
hassfest:
name: Hassfest validation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: Vendor the astrameter package into the integration
run: python3 scripts/assemble_integration.py --vendor-only
- name: Hassfest
uses: home-assistant/actions/hassfest@master
package:
name: Build installable artifact
runs-on: ubuntu-latest
# Needed to post/update the install-links comment on pull requests.
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.13"
# Assemble the integration the same way a release does, but stamp an
# identifiable pre-release version (the patch bump + this run number) so a
# manually installed PR build is distinguishable from a real release.
- name: Assemble astrameter.zip
id: assemble
run: |
VERSION="$(python scripts/assemble_integration.py --print-beta-version "${{ github.run_number }}")"
python scripts/assemble_integration.py --version "$VERSION" --output dist/astrameter.zip
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Built astrameter $VERSION"
# The folder artifact extracts straight into config/custom_components/astrameter/.
- name: Upload custom_components/astrameter (drop into your HA config)
id: upload_folder
uses: actions/upload-artifact@v4
with:
name: astrameter-custom-component
path: dist/astrameter/
if-no-files-found: error
# The zip artifact is the exact asset HACS installs (zip-of-zip on download).
- name: Upload astrameter.zip (HACS-shaped release asset)
id: upload_zip
uses: actions/upload-artifact@v4
with:
name: astrameter-zip
path: dist/astrameter.zip
if-no-files-found: error
# Post a single sticky comment with the download links and refresh it on
# every rebuild (found by the hidden marker) instead of spamming the PR.
# Skipped for fork PRs, whose GITHUB_TOKEN is read-only.
- name: Comment install links on the PR
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
uses: actions/github-script@v7
with:
script: |
const marker = '<!-- astrameter-build-artifact -->';
const version = ${{ toJSON(steps.assemble.outputs.version) }};
const folderUrl = ${{ toJSON(steps.upload_folder.outputs['artifact-url']) }};
const zipUrl = ${{ toJSON(steps.upload_zip.outputs['artifact-url']) }};
const sha = context.payload.pull_request.head.sha.slice(0, 7);
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
const body = [
marker,
`### 📦 Installable build for this PR`,
``,
`Built **astrameter \`${version}\`** from \`${sha}\` ([run](${runUrl})). ` +
`Install this branch manually — no release needed:`,
``,
`- **[\`astrameter-custom-component\`](${folderUrl})** — unzip into ` +
`\`config/custom_components/astrameter/\` (HA Container/Core), then restart HA.`,
`- **[\`astrameter-zip\`](${zipUrl})** — the HACS-shaped release asset ` +
`(GitHub wraps it, so it downloads as a zip-of-zip).`,
``,
`<sub>Downloading a workflow artifact requires being signed in to GitHub. ` +
`Artifacts expire after 90 days. This comment updates on every push.</sub>`,
].join('\n');
const { owner, repo } = context.repo;
const issue_number = context.issue.number;
const comments = await github.paginate(github.rest.issues.listComments, {
owner, repo, issue_number,
});
const existing = comments.find((c) => c.body && c.body.includes(marker));
if (existing) {
await github.rest.issues.updateComment({
owner, repo, comment_id: existing.id, body,
});
} else {
await github.rest.issues.createComment({ owner, repo, issue_number, body });
}