Skip to content

Release & Publish to NPM #16

Release & Publish to NPM

Release & Publish to NPM #16

Workflow file for this run

name: Release & Publish to NPM
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
version:
description: "Version to publish (e.g., 1.0.0)"
required: true
type: string
release:
types: [published]
# Empêche les publications en double si tag + release se déclenchent
concurrency:
group: publish-${{ github.ref || github.event.release.tag_name || github.event.inputs.version }}
cancel-in-progress: false
permissions:
contents: write
id-token: write
env:
NODE_VERSION: "22"
CI: "true"
defaults:
run:
shell: bash
jobs:
test-before-publish:
name: Tests & Quality Check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Verify submodules
run: |
echo "Checking submodule status..."
git submodule status
echo "Listing external directory..."
ls -la external/ || true
if [ ! -f "external/soem/CMakeLists.txt" ]; then
echo "SOEM submodule not properly initialized, initializing..."
git submodule update --init --recursive --force
ls -la external/soem/ || true
fi
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
check-latest: true
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Lint check
run: npm run lint:check
# Option A: rendre non-bloquant (souvent préférable)
- name: Security audit
run: npm audit --audit-level=high
continue-on-error: true
- name: Run tests with coverage
run: npm run test:ci
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
file: ./coverage/lcov.info
flags: unittests
name: codecov-umbrella
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
build-binaries:
name: Build on ${{ matrix.os }}
needs: test-before-publish
strategy:
matrix:
os: [ubuntu-latest, windows-latest] # ajoute macos-latest si besoin
include:
- os: ubuntu-latest
platform: linux
- os: windows-latest
platform: win32
# - os: macos-latest
# platform: darwin
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Verify submodules
shell: bash
run: |
echo "Checking submodule status..."
git submodule status
echo "Listing external directory..."
ls -la external/ || mkdir -p external
if [ ! -f "external/soem/CMakeLists.txt" ]; then
echo "SOEM submodule not properly initialized, trying multiple methods..."
git submodule deinit -f external/soem || true
rm -rf external/soem
git submodule update --init --recursive --force || echo "Method 1 failed"
if [ ! -f "external/soem/CMakeLists.txt" ]; then
echo "Direct clone fallback..."
rm -rf external/soem
git clone --depth=1 --branch=master https://github.com/OpenEtherCATsociety/SOEM.git external/soem
fi
if [ ! -f "external/soem/CMakeLists.txt" ]; then
echo "ERROR: Could not initialize SOEM submodule properly"
ls -la external/soem/ || echo "Directory doesn't exist"
exit 1
fi
echo "SOEM successfully initialized:"
ls -la external/soem/
else
echo "SOEM submodule already properly initialized"
fi
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
check-latest: true
cache: "npm"
- name: Install system dependencies (Linux)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libpcap-dev cmake build-essential
- name: Install system dependencies (Windows)
if: matrix.os == 'windows-latest'
shell: powershell
run: |
Write-Host "Windows runner already has toolchains; proceeding."
- name: Install dependencies
run: npm ci
- name: Build native addon
run: npm run build
- name: Test binary & outputs
shell: bash
run: |
echo "Testing binary on ${{ matrix.platform }}..."
test -f build/Release/soem_addon.node || (ls -la build/Release/ || true; exit 1)
test -f dist/index.js || (ls -la dist/ || true; exit 1)
if [ -f types/index.d.ts ]; then echo "✓ TypeScript definitions present"; else echo "✗ Missing types"; exit 1; fi
node ./scripts/ci-test-module.js || true
# ⚠️ Ces artefacts ne sont utiles que si tu les publies/re-distribues (prebuilds)
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-${{ matrix.platform }}
path: |
build/Release/soem_addon.node
dist/
types/
retention-days: 1
publish-npm:
name: Publish to NPM
needs: [test-before-publish, build-binaries]
runs-on: ubuntu-latest
# Publie seulement sur tag v* ou via dispatch
if: >
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) ||
(github.event_name == 'workflow_dispatch') ||
(github.event_name == 'release' && github.event.action == 'published')
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Verify submodules
run: |
git submodule update --init --recursive --force
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
check-latest: true
registry-url: "https://registry.npmjs.org"
cache: "npm"
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libpcap-dev cmake build-essential
- name: Install dependencies
run: npm ci
- name: Resolve version to publish
id: get_version
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
VERSION="${{ github.event.inputs.version }}"
elif [[ "${{ github.event_name }}" == "release" ]]; then
VERSION="${{ github.event.release.tag_name }}"
VERSION="${VERSION#v}"
else
VERSION="${GITHUB_REF#refs/tags/v}"
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Publishing version: $VERSION"
- name: Update package.json version
id: set_version
env:
VERSION: ${{ steps.get_version.outputs.version }}
run: |
echo "Setting package.json version to $VERSION"
node -e "const fs=require('fs');const v=process.env.VERSION;const p=JSON.parse(fs.readFileSync('package.json','utf8'));p.version=v;fs.writeFileSync('package.json',JSON.stringify(p,null,2)+'\n');console.log('package.json version set to',p.version)"
- name: Verify package.json version changed
run: |
NEW=$(node -e "console.log(require('./package.json').version)")
echo "package.json version is $NEW"
if [ "$NEW" = "${{ steps.get_version.outputs.version }}" ]; then
echo "Version correctly set"
else
echo "Version mismatch: expected ${{ steps.get_version.outputs.version }}, got $NEW"
exit 1
fi
- name: Commit package.json and create tag (workflow_dispatch only)
if: github.event_name == 'workflow_dispatch'
env:
VERSION: ${{ steps.get_version.outputs.version }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "Committing package.json and creating tag v$VERSION"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add package.json
# Commit if there are changes
if git diff --staged --quiet; then
echo "No changes to commit"
else
git commit -m "chore(release): v$VERSION"
# Push the commit to the current branch
git push origin HEAD
fi
# Create annotated tag if it does not already exist
git fetch --tags
if git rev-parse "v$VERSION" >/dev/null 2>&1; then
echo "Tag v$VERSION already exists, skipping tag creation"
else
git tag -a "v$VERSION" -m "Release v$VERSION"
git push origin "v$VERSION"
fi
- name: Build for publication
run: npm run build
- name: Run final tests
run: npm test
- name: Publish to NPM (with provenance)
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
# --access public si besoin (package public ou scope)
npm publish --provenance --access public
- name: Create GitHub Release if needed
if: github.event_name != 'release'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ steps.get_version.outputs.version }}"
gh release create "v${VERSION}" \
--title "Release v${VERSION}" \
--notes "## 🚀 Release v${VERSION}
### 📦 NPM Package
\`\`\`bash
npm install soem-node@${VERSION}
\`\`\`
### 🔗 Links
- NPM : https://www.npmjs.com/package/soem-node/v/${VERSION}
- Repo : https://github.com/MXASoundNDEv/SOEM-Nodejs
- Docs : https://github.com/MXASoundNDEv/SOEM-Nodejs#readme
### 📋 Changes
Voir [CHANGELOG.md](https://github.com/MXASoundNDEv/SOEM-Nodejs/blob/main/CHANGELOG.md)."
notify-success:
name: Notify Success
needs: [publish-npm]
runs-on: ubuntu-latest
if: success()
steps:
- name: Success notification
run: |
echo "🎉 Publication réussie !"
echo "📦 Package publié sur NPM"
echo "🔗 NPM: https://www.npmjs.com/package/soem-node"