name: Test and Release on: push: tags: - 'v*' workflow_dispatch: jobs: validate: name: Validate Integration runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Hassfest Validation uses: home-assistant/actions/hassfest@master - name: HACS Validation uses: hacs/action@main with: category: "integration" determine-integration: name: Determine Integration Name runs-on: ubuntu-latest outputs: integration_name: ${{ steps.get_name.outputs.integration_name }} steps: - name: Checkout repository uses: actions/checkout@v4 - name: Get integration name id: get_name run: | INTEGRATION_NAME=$(find custom_components -mindepth 1 -maxdepth 1 -type d -exec test -f {}/manifest.json \; -print -quit | xargs basename) echo "integration_name=$INTEGRATION_NAME" >> $GITHUB_OUTPUT test: name: Run Tests runs-on: ubuntu-latest needs: [validate, determine-integration] steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install dependencies run: | python -m pip install --upgrade pip pip install pytest pytest-homeassistant-custom-component if [ -f requirements_test.txt ]; then pip install -r requirements_test.txt; fi - name: Run tests run: | if [ -d "tests" ]; then pytest tests/ --cov=custom_components/${{ needs.determine-integration.outputs.integration_name }} --cov-report=xml else echo "No tests directory found, skipping tests" fi lint: name: Code Quality runs-on: ubuntu-latest needs: [validate, determine-integration] steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install linters run: | pip install black ruff mypy - name: Check code formatting with black run: | black --check custom_components/${{ needs.determine-integration.outputs.integration_name }}/ || echo "Code formatting issues found" - name: Check code with ruff run: | ruff check custom_components/${{ needs.determine-integration.outputs.integration_name }}/ || echo "Ruff issues found" release: name: Create Release runs-on: ubuntu-latest needs: [validate, test, lint] permissions: contents: write steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - name: Get tag info id: tag run: | TAG=${GITHUB_REF#refs/tags/} echo "tag=$TAG" >> $GITHUB_OUTPUT if [[ "$TAG" == *"beta"* ]]; then echo "is_beta=true" >> $GITHUB_OUTPUT else echo "is_beta=false" >> $GITHUB_OUTPUT fi PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") if [ -z "$PREV_TAG" ]; then COMMITS=$(git log --pretty=format:"- %s" --reverse) else COMMITS=$(git log ${PREV_TAG}..HEAD --pretty=format:"- %s" --reverse) fi echo "commits<> $GITHUB_OUTPUT echo "$COMMITS" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - name: Create GitHub Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | TAG="${{ steps.tag.outputs.tag }}" COMMITS="${{ steps.tag.outputs.commits }}" IS_BETA="${{ steps.tag.outputs.is_beta }}" echo "Creating release $TAG in GitHub..." if [ "$IS_BETA" = "true" ]; then TITLE="Beta Release $TAG" else TITLE="Release $TAG" fi cat > /tmp/release_notes.md << EOF ## $TITLE $COMMITS EOF if [ "$IS_BETA" = "true" ]; then gh release create "$TAG" \ --title "$TITLE" \ --notes-file /tmp/release_notes.md \ --target main \ --prerelease else gh release create "$TAG" \ --title "$TITLE" \ --notes-file /tmp/release_notes.md \ --target main fi echo "Release created successfully!"