Skip to content
This repository was archived by the owner on Nov 14, 2025. It is now read-only.

Commit e17faac

Browse files
sapientpantsclaude
andauthored
fix: resolve NPM husky and Docker OCI format issues in publish workflow (#313)
Two critical fixes for the Publish workflow: 1. NPM Publish Fix: - Added --ignore-scripts flag to npm publish commands - Prevents prepare script from running husky (devDependency) - Husky is not available in extracted NPM packages 2. Docker Publish Fix: - Install skopeo to handle OCI format images - Multi-platform builds from Main workflow use OCI format - docker load doesn't support OCI, replaced with skopeo copy - Skopeo converts OCI archive to docker-daemon format These issues caused v1.10.9 publish to fail with: - NPM: "sh: 1: husky: not found" error - Docker: "no such file or directory" when loading OCI image 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <[email protected]>
1 parent ee64b02 commit e17faac

File tree

2 files changed

+36
-17
lines changed

2 files changed

+36
-17
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'sonarqube-mcp-server': patch
3+
---
4+
5+
Fix NPM and Docker publish failures
6+
7+
- NPM: Add --ignore-scripts flag to prevent husky from running during publish
8+
- Docker: Use skopeo to load OCI format images from multi-platform builds instead of docker load

.github/workflows/publish.yml

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ jobs:
153153
jq 'del(.private)' package.json > tmp.json && mv tmp.json package.json
154154
# Publish with provenance for supply chain security
155155
# --provenance creates a signed attestation of the build
156-
npm publish --provenance --access public
156+
# --ignore-scripts prevents running prepare/prepack scripts (husky) during publish
157+
npm publish --provenance --access public --ignore-scripts
157158
env:
158159
# SECURITY: NPM_TOKEN required for authentication
159160
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -247,7 +248,8 @@ jobs:
247248
# Scope package name to organization (required for GitHub Packages)
248249
# Changes 'my-package' to '@org/my-package'
249250
jq '.name = "@${{ github.repository_owner }}/" + .name | del(.private)' package.json > tmp.json && mv tmp.json package.json
250-
npm publish --access public
251+
# --ignore-scripts prevents running prepare/prepack scripts (husky) during publish
252+
npm publish --access public --ignore-scripts
251253
env:
252254
# SECURITY: Uses GITHUB_TOKEN for authentication
253255
# Automatically available, no configuration needed
@@ -354,35 +356,44 @@ jobs:
354356
username: ${{ secrets.DOCKERHUB_USERNAME }}
355357
password: ${{ secrets.DOCKERHUB_TOKEN }}
356358

359+
- name: Install skopeo
360+
# Skopeo is needed to handle OCI format images from multi-platform builds
361+
if: steps.check-docker.outputs.has_credentials == 'true'
362+
run: |
363+
sudo apt-get update
364+
sudo apt-get install -y skopeo
365+
357366
- name: Load and push Docker image
358-
# Load the pre-built image and push with proper tags
367+
# Load the pre-built OCI image and push with proper tags
359368
if: steps.check-docker.outputs.has_credentials == 'true'
360369
run: |
361370
echo "📥 Decompressing Docker image..."
362371
gunzip ./docker-artifact/${{ steps.artifact.outputs.artifact_name }}.tar.gz
363372
364-
echo "🔄 Loading Docker image..."
365-
docker load < ./docker-artifact/${{ steps.artifact.outputs.artifact_name }}.tar
366-
367-
# The image is already tagged with the version from the main build
368-
# We need to retag it with the Docker Hub repository name
369-
# Note: This must match the image-name parameter in main.yml's docker job
373+
# The artifact is in OCI format (for multi-platform builds)
374+
# We need to use skopeo to copy it to docker-daemon
370375
SOURCE_IMAGE_NAME="sonarqube-mcp-server"
371-
SOURCE_IMAGE="$SOURCE_IMAGE_NAME:${{ steps.version.outputs.version }}"
372376
TARGET_REPO="${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }}"
377+
VERSION="${{ steps.version.outputs.version }}"
378+
379+
echo "🔄 Loading OCI image to Docker daemon..."
380+
# Use skopeo to copy from OCI archive to docker-daemon
381+
# The tag in the OCI archive should match what was built in Main workflow
382+
skopeo copy \
383+
oci-archive:./docker-artifact/${{ steps.artifact.outputs.artifact_name }}.tar:$SOURCE_IMAGE_NAME:$VERSION \
384+
docker-daemon:$TARGET_REPO:$VERSION
373385
374386
echo "🏷️ Tagging image for Docker Hub..."
375-
docker tag "$SOURCE_IMAGE" "$TARGET_REPO:${{ steps.version.outputs.version }}"
376-
docker tag "$SOURCE_IMAGE" "$TARGET_REPO:latest"
387+
docker tag "$TARGET_REPO:$VERSION" "$TARGET_REPO:latest"
377388
378389
# Also add major and major.minor tags
379-
MAJOR=$(echo "${{ steps.version.outputs.version }}" | cut -d. -f1)
380-
MINOR=$(echo "${{ steps.version.outputs.version }}" | cut -d. -f2)
381-
docker tag "$SOURCE_IMAGE" "$TARGET_REPO:$MAJOR"
382-
docker tag "$SOURCE_IMAGE" "$TARGET_REPO:$MAJOR.$MINOR"
390+
MAJOR=$(echo "$VERSION" | cut -d. -f1)
391+
MINOR=$(echo "$VERSION" | cut -d. -f2)
392+
docker tag "$TARGET_REPO:$VERSION" "$TARGET_REPO:$MAJOR"
393+
docker tag "$TARGET_REPO:$VERSION" "$TARGET_REPO:$MAJOR.$MINOR"
383394
384395
echo "📤 Pushing to Docker Hub..."
385-
docker push "$TARGET_REPO:${{ steps.version.outputs.version }}"
396+
docker push "$TARGET_REPO:$VERSION"
386397
docker push "$TARGET_REPO:latest"
387398
docker push "$TARGET_REPO:$MAJOR"
388399
docker push "$TARGET_REPO:$MAJOR.$MINOR"

0 commit comments

Comments
 (0)