From 521d120425f67ea93fd54a2c06b4b5ca1e8868a3 Mon Sep 17 00:00:00 2001 From: "hugh-hackman[bot]" Date: Sun, 8 Mar 2026 00:44:51 +0000 Subject: [PATCH] feat: add reusable CI and release workflows for Headlamp plugins --- .github/workflows/plugin-ci.yaml | 43 ++++++++ .github/workflows/plugin-release.yaml | 138 ++++++++++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 .github/workflows/plugin-ci.yaml create mode 100644 .github/workflows/plugin-release.yaml diff --git a/.github/workflows/plugin-ci.yaml b/.github/workflows/plugin-ci.yaml new file mode 100644 index 0000000..a1ba824 --- /dev/null +++ b/.github/workflows/plugin-ci.yaml @@ -0,0 +1,43 @@ +name: Plugin CI + +on: + workflow_call: + inputs: + node-version: + description: 'Node.js version to use' + required: false + type: string + default: '22' + +jobs: + ci: + runs-on: local-ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ inputs.node-version }} + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Build plugin + run: npx @kinvolk/headlamp-plugin build + + - name: Lint + run: npm run lint + + - name: Type-check + run: npm run tsc + + - name: Format check + run: npm run format:check + + - name: Run tests + run: npm test diff --git a/.github/workflows/plugin-release.yaml b/.github/workflows/plugin-release.yaml new file mode 100644 index 0000000..89c8fd8 --- /dev/null +++ b/.github/workflows/plugin-release.yaml @@ -0,0 +1,138 @@ +name: Plugin Release + +on: + workflow_call: + inputs: + version: + description: 'Release version (e.g. 1.0.0)' + required: true + type: string + node-version: + description: 'Node.js version to use' + required: false + type: string + default: '22' + upstream-repo: + description: 'Upstream repo to fetch appVersion from (e.g. fenio/tns-csi). Leave empty to skip.' + required: false + type: string + default: '' + +permissions: + contents: write + +concurrency: + group: release + cancel-in-progress: false + +jobs: + ci: + uses: ./.github/workflows/plugin-ci.yaml + with: + node-version: ${{ inputs.node-version }} + + release: + needs: ci + runs-on: local-ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Validate version format + run: | + if [[ ! "${{ inputs.version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Error: Version must be in X.Y.Z format" + exit 1 + fi + + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ inputs.node-version }} + cache: 'npm' + + - name: Configure Git + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Update version in package.json + run: npm version ${{ inputs.version }} --no-git-tag-version --allow-same-version + + - name: Update artifacthub-pkg.yml + run: | + VERSION="${{ inputs.version }}" + PKG_NAME=$(jq -r .name package.json) + RELEASE_URL="https://github.com/${{ github.repository }}/releases/download/v${VERSION}/${PKG_NAME}-${VERSION}.tar.gz" + sed -i "s/^version:.*/version: \"${VERSION}\"/" artifacthub-pkg.yml + sed -i "s|headlamp/plugin/archive-url:.*|headlamp/plugin/archive-url: \"${RELEASE_URL}\"|" artifacthub-pkg.yml + + - name: Update appVersion from upstream release + if: inputs.upstream-repo != '' + run: | + APP_VERSION=$(curl -sf "https://api.github.com/repos/${{ inputs.upstream-repo }}/releases/latest" | jq -r '.tag_name | ltrimstr("v")') + if [ -z "$APP_VERSION" ] || [ "$APP_VERSION" = "null" ]; then + echo "::warning::Could not fetch latest upstream release, skipping appVersion update" + else + sed -i "s|^appVersion:.*|appVersion: \"${APP_VERSION}\"|" artifacthub-pkg.yml + echo "appVersion set to ${APP_VERSION}" + fi + + - name: Install dependencies + run: npm ci + + - name: Build plugin + run: npx @kinvolk/headlamp-plugin build + + - name: Package plugin + run: npx @kinvolk/headlamp-plugin package + + - name: Prepare release tarball + run: | + VERSION="${{ inputs.version }}" + PKG_NAME=$(jq -r .name package.json) + TARBALL="${PKG_NAME}-${VERSION}.tar.gz" + # Rename tarball if headlamp-plugin produced a different name + for f in *.tar.gz; do + [ "$f" != "$TARBALL" ] && mv "$f" "$TARBALL" + done + if [ ! -f "$TARBALL" ]; then + echo "Error: Expected tarball $TARBALL not found" + ls -la *.tar.gz 2>/dev/null || echo "No .tar.gz files found" + exit 1 + fi + echo "TARBALL=$TARBALL" >> $GITHUB_ENV + echo "PKG_NAME=$PKG_NAME" >> $GITHUB_ENV + + - name: Validate tarball + run: | + echo "Tarball: ${{ env.TARBALL }}" + ls -lh "${{ env.TARBALL }}" + tar -tzf "${{ env.TARBALL }}" | head -20 + tar -tzf "${{ env.TARBALL }}" | grep -q "main.js" || { echo "Error: main.js not found in tarball"; exit 1; } + + - name: Compute checksum + run: | + CHECKSUM=$(sha256sum "${{ env.TARBALL }}" | awk '{print $1}') + echo "CHECKSUM=$CHECKSUM" >> $GITHUB_ENV + sed -i "s|headlamp/plugin/archive-checksum:.*|headlamp/plugin/archive-checksum: sha256:${CHECKSUM}|" artifacthub-pkg.yml + + - name: Commit and tag + run: | + VERSION="${{ inputs.version }}" + git add package.json package-lock.json artifacthub-pkg.yml + git commit -m "release: v${VERSION}" + git tag "v${VERSION}" + git push origin main --tags + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: "v${{ inputs.version }}" + files: ${{ env.TARBALL }} + fail_on_unmatched_files: true + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}