diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yaml similarity index 80% rename from .github/workflows/ci.yml rename to .github/workflows/ci.yaml index 0e59d8b..bc28d72 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yaml @@ -2,17 +2,17 @@ name: CI on: push: - branches: [ main ] + branches: [main] pull_request: - branches: [ main ] + branches: [main] jobs: - test: + lint-and-test: runs-on: local-ubuntu-latest timeout-minutes: 10 steps: - - name: Checkout code + - name: Checkout uses: actions/checkout@v4 - name: Setup Node.js @@ -26,26 +26,26 @@ jobs: working-directory: ./headlamp-sealed-secrets run: npm ci - - name: Run type check + - name: Type-check working-directory: ./headlamp-sealed-secrets run: npm run tsc - - name: Run linter + - name: Lint working-directory: ./headlamp-sealed-secrets run: npm run lint - name: Build plugin working-directory: ./headlamp-sealed-secrets - run: npm run build + run: npx @kinvolk/headlamp-plugin build - name: Verify build artifacts working-directory: ./headlamp-sealed-secrets run: | if [ ! -d "dist" ] || [ -z "$(ls -A dist)" ]; then - echo "Error: dist directory is empty or missing" + echo "::error::dist directory is empty or missing" exit 1 fi - echo "Build artifacts verified successfully" + echo "✓ Build artifacts verified" ls -lh dist/ - name: Upload build artifact (for inspection) diff --git a/.github/workflows/prepare-release.yaml b/.github/workflows/prepare-release.yaml new file mode 100644 index 0000000..8af87ce --- /dev/null +++ b/.github/workflows/prepare-release.yaml @@ -0,0 +1,67 @@ +name: Prepare Release + +on: + workflow_dispatch: + inputs: + version: + description: 'Version to release (without v prefix, e.g., 0.2.5)' + required: true + type: string + +jobs: + prepare: + runs-on: local-ubuntu-latest + steps: + - name: Validate version format + run: | + if ! echo "${{ inputs.version }}" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "::error::Version must be in format X.Y.Z (e.g., 0.2.5)" + exit 1 + fi + + - name: Checkout + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Configure git + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Update package.json version + working-directory: ./headlamp-sealed-secrets + run: | + jq --arg version "${{ inputs.version }}" '.version = $version' package.json > package.json.tmp + mv package.json.tmp package.json + + - name: Update artifacthub-pkg.yml version + run: | + VERSION="${{ inputs.version }}" + RELEASE_URL="https://github.com/${{ github.repository }}/releases/download/v${VERSION}/headlamp-sealed-secrets-${VERSION}.tar.gz" + + sed -i "s|^version:.*|version: ${VERSION}|" artifacthub-pkg.yml + sed -i "s|^appVersion:.*|appVersion: ${VERSION}|" artifacthub-pkg.yml + sed -i "s|headlamp/plugin/archive-url:.*|headlamp/plugin/archive-url: \"${RELEASE_URL}\"|" artifacthub-pkg.yml + + # Set placeholder checksum - will be updated after release + sed -i "s|headlamp/plugin/archive-checksum:.*|headlamp/plugin/archive-checksum: sha256:PLACEHOLDER_WILL_BE_UPDATED_AFTER_RELEASE|" artifacthub-pkg.yml + + - name: Commit version bump + run: | + git add headlamp-sealed-secrets/package.json artifacthub-pkg.yml + git commit -m "chore: bump version to ${{ inputs.version }}" + git push origin main + + - name: Create and push tag + run: | + git tag "v${{ inputs.version }}" + git push origin "v${{ inputs.version }}" + + - name: Summary + run: | + echo "✓ Version bumped to ${{ inputs.version }}" + echo "✓ Tag v${{ inputs.version }} created" + echo "" + echo "The release workflow will now run automatically." + echo "After it completes, the checksum will be updated on main." diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 68213f1..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,166 +0,0 @@ -name: Publish Release - -on: - push: - tags: - - 'v*' - workflow_dispatch: - -jobs: - publish: - runs-on: local-ubuntu-latest - timeout-minutes: 15 - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'npm' - cache-dependency-path: headlamp-sealed-secrets/package-lock.json - - - name: Extract version from tag - id: version - run: | - VERSION=${GITHUB_REF#refs/tags/v} - echo "version=${VERSION}" >> $GITHUB_OUTPUT - echo "Version: ${VERSION}" - - - name: Install dependencies - working-directory: ./headlamp-sealed-secrets - run: npm ci - - - name: Run type check - working-directory: ./headlamp-sealed-secrets - run: npm run tsc - - - name: Run linter - working-directory: ./headlamp-sealed-secrets - run: npm run lint - - - name: Build plugin (deterministic) - working-directory: ./headlamp-sealed-secrets - run: npm run build - env: - NODE_ENV: production - - - name: Create tarball (deterministic packaging) - id: tarball - working-directory: ./headlamp-sealed-secrets - run: | - # Use npm pack to create deterministic tarball - TARBALL=$(npm pack --json | jq -r '.[0].filename') - - # Move to parent directory for release - mv "${TARBALL}" "../${TARBALL}" - - # Calculate SHA256 checksum - CHECKSUM=$(sha256sum "../${TARBALL}" | awk '{print $1}') - - echo "tarball=${TARBALL}" >> $GITHUB_OUTPUT - echo "checksum=${CHECKSUM}" >> $GITHUB_OUTPUT - echo "Tarball: ${TARBALL}" - echo "Checksum: SHA256:${CHECKSUM}" - - - name: Verify tarball contents - id: verify - run: | - TARBALL="${{ steps.tarball.outputs.tarball }}" - echo "Verifying tarball: ${TARBALL}" - - # List tarball contents - tar -tzf "${TARBALL}" | head -20 - - # Verify main.js exists - if ! tar -tzf "${TARBALL}" | grep -q "package/dist/main.js"; then - echo "Error: main.js not found in tarball" - exit 1 - fi - - # Get file size - SIZE=$(ls -lh "${TARBALL}" | awk '{print $5}') - echo "Size: ${SIZE}" - - - name: Create GitHub Release - uses: softprops/action-gh-release@v1 - with: - tag_name: ${{ github.ref_name }} - files: ${{ steps.tarball.outputs.tarball }} - generate_release_notes: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Update artifacthub-pkg.yml with checksum - id: update-metadata - run: | - VERSION="${{ steps.version.outputs.version }}" - CHECKSUM="${{ steps.tarball.outputs.checksum }}" - ARCHIVE_URL="https://github.com/${{ github.repository }}/releases/download/v${VERSION}/${{ steps.tarball.outputs.tarball }}" - - # Update version, checksum, and archive URL in artifacthub-pkg.yml - python3 << 'EOF' - import yaml - import sys - - version = "${{ steps.version.outputs.version }}" - checksum = "${{ steps.tarball.outputs.checksum }}" - archive_url = "$ARCHIVE_URL" - - with open('artifacthub-pkg.yml', 'r') as f: - data = yaml.safe_load(f) - - # Update version fields - data['version'] = version - data['appVersion'] = version - - # Update annotations with archive URL and checksum - data['annotations']['headlamp/plugin/archive-url'] = archive_url - data['annotations']['headlamp/plugin/archive-checksum'] = f'SHA256:{checksum}' - - with open('artifacthub-pkg.yml', 'w') as f: - yaml.dump(data, f, sort_keys=False, default_flow_style=False) - - print(f"Updated artifacthub-pkg.yml:") - print(f" Version: {version}") - print(f" Checksum: SHA256:{checksum}") - print(f" Archive URL: {archive_url}") - EOF - - - name: Verify metadata update - run: | - echo "Updated artifacthub-pkg.yml:" - grep -A 2 "version:" artifacthub-pkg.yml | head -5 - grep "archive-url:" artifacthub-pkg.yml - grep "archive-checksum:" artifacthub-pkg.yml - - - name: Commit metadata update - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - # Check if there are changes to commit - if git diff --quiet artifacthub-pkg.yml; then - echo "No changes to commit (metadata already up to date)" - else - echo "Committing metadata update..." - git add artifacthub-pkg.yml - git commit -m "chore(release): update checksums for v${{ steps.version.outputs.version }}" - git push origin main - fi - - - name: Print release summary - run: | - echo "Release Summary:" - echo "==================" - echo "Version: v${{ steps.version.outputs.version }}" - echo "Tarball: ${{ steps.tarball.outputs.tarball }}" - echo "Checksum: SHA256:${{ steps.tarball.outputs.checksum }}" - echo "Archive URL: https://github.com/${{ github.repository }}/releases/download/v${{ steps.version.outputs.version }}/${{ steps.tarball.outputs.tarball }}" - echo "" - echo "Next: Verify on Artifact Hub (5-10 minutes)" - echo "https://artifacthub.io/packages/headlamp-sealed-secrets" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..0990fc2 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,146 @@ +name: Release + +on: + push: + tags: + - 'v*' + +jobs: + build-and-release: + runs-on: local-ubuntu-latest + permissions: + contents: write + outputs: + version: ${{ steps.extract_version.outputs.version }} + checksum: ${{ steps.compute_checksum.outputs.checksum }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Extract version from tag + id: extract_version + run: | + VERSION=${GITHUB_REF_NAME#v} + echo "version=${VERSION}" >> $GITHUB_OUTPUT + echo "Version: ${VERSION}" + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: headlamp-sealed-secrets/package-lock.json + + - name: Install dependencies + working-directory: ./headlamp-sealed-secrets + run: npm ci + + - name: Run type check + working-directory: ./headlamp-sealed-secrets + run: npm run tsc + + - name: Run linter + working-directory: ./headlamp-sealed-secrets + run: npm run lint + + - name: Build plugin + working-directory: ./headlamp-sealed-secrets + run: npx @kinvolk/headlamp-plugin build + + - name: Package plugin + working-directory: ./headlamp-sealed-secrets + run: npx @kinvolk/headlamp-plugin package + + - name: Move tarball to root + working-directory: ./headlamp-sealed-secrets + run: | + TARBALL=$(ls *.tar.gz) + mv "${TARBALL}" "../${TARBALL}" + echo "Moved tarball: ${TARBALL}" + + - name: Validate tarball name + run: | + EXPECTED="headlamp-sealed-secrets-${{ steps.extract_version.outputs.version }}.tar.gz" + ACTUAL=$(ls *.tar.gz) + if [ "$EXPECTED" != "$ACTUAL" ]; then + echo "::error::Tarball name mismatch! Expected: $EXPECTED, Got: $ACTUAL" + exit 1 + fi + echo "✓ Tarball name validated: $ACTUAL" + + - name: Compute checksum + id: compute_checksum + run: | + TARBALL="headlamp-sealed-secrets-${{ steps.extract_version.outputs.version }}.tar.gz" + CHECKSUM=$(sha256sum "$TARBALL" | awk '{print $1}') + echo "checksum=${CHECKSUM}" >> $GITHUB_OUTPUT + echo "Checksum: sha256:${CHECKSUM}" + + - name: Verify tarball contents + run: | + TARBALL="headlamp-sealed-secrets-${{ steps.extract_version.outputs.version }}.tar.gz" + echo "Tarball contents:" + tar -tzf "${TARBALL}" | head -20 + + # Verify main.js exists + if ! tar -tzf "${TARBALL}" | grep -q "package/main.js"; then + echo "::error::main.js not found in tarball" + exit 1 + fi + echo "✓ Tarball contents validated" + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + files: headlamp-sealed-secrets-${{ steps.extract_version.outputs.version }}.tar.gz + fail_on_unmatched_files: true + draft: false + prerelease: false + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + update-metadata: + needs: build-and-release + runs-on: local-ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout main branch + uses: actions/checkout@v4 + with: + ref: main + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Configure git + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Update checksum in metadata + run: | + VERSION="${{ needs.build-and-release.outputs.version }}" + CHECKSUM="${{ needs.build-and-release.outputs.checksum }}" + + sed -i "s|headlamp/plugin/archive-checksum:.*|headlamp/plugin/archive-checksum: sha256:${CHECKSUM}|" artifacthub-pkg.yml + + git add artifacthub-pkg.yml + if ! git diff --cached --quiet; then + git commit -m "ci: update checksum for v${VERSION}" + git push origin main + echo "✓ Checksum updated on main branch" + else + echo "✓ Checksum already up to date" + fi + + - name: Release Summary + run: | + echo "Release Summary:" + echo "==================" + echo "Version: v${{ needs.build-and-release.outputs.version }}" + echo "Tarball: headlamp-sealed-secrets-${{ needs.build-and-release.outputs.version }}.tar.gz" + echo "Checksum: sha256:${{ needs.build-and-release.outputs.checksum }}" + echo "Archive URL: https://github.com/${{ github.repository }}/releases/download/v${{ needs.build-and-release.outputs.version }}/headlamp-sealed-secrets-${{ needs.build-and-release.outputs.version }}.tar.gz" + echo "" + echo "Metadata updated on main branch." + echo "Artifact Hub will sync within 5-10 minutes."