Skip to content

Publish

Publish #146

Workflow file for this run

name: Publish
on:
workflow_dispatch:
push:
tags:
- "v*.*.*"
env:
# Necessary for most environments as build failure can occur due to OOM issues
NODE_OPTIONS: "--max-old-space-size=4096"
ARTIFACT_NAME_PREFIX: "SCANOSS Code Compare"
GOLANG_VERSION: "1.21"
NODE_VERSION: "16.x"
jobs:
build_mac:
name: Build for MacOS
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
fetch-tags: true
# Setup and configure GoLang
- name: Setup GoLang
uses: actions/setup-go@v5
with:
check-latest: true
go-version: ${{ env.GOLANG_VERSION }}
- run: go version
shell: bash
# Setup and configure NodeJS
- name: Setup NodeJS
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
# Install Wails
- name: Install Wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
shell: bash
# Build
- name: Build App
run: |
mkdir -p build
cp -r assets build/assets
cp assets/appicon.png build
wails build -ldflags "-X github.com/scanoss/scanoss.cc/backend/entities.AppVersion=$(git tag --sort=-version:refname | head -n 1)" --platform "darwin/universal" -o "${{ env.ARTIFACT_NAME_PREFIX }}"
shell: bash
# Make sure the .app exists
- name: Check .app
run: ls -l "build/bin/${{ env.ARTIFACT_NAME_PREFIX }}.app" || (echo ".app not found!" && exit 1)
- name: Import Code-Signing Certificates for macOS
uses: Apple-Actions/import-codesign-certs@v3
with:
keychain: signing_app
keychain-password: ${{ secrets.APPLE_PASSWORD }}
p12-file-base64: ${{ secrets.MACOS_DEVELOPER_CERT }}
p12-password: ${{ secrets.MACOS_DEVELOPER_CERT_PASSWORD }}
- name: Sign .app Bundle
env:
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_ID: [email protected]
APP_CERTIFICATE: ${{ secrets.MACOS_DEVELOPER_CERT_FULL_ID }}
APPLE_DEVELOPER_ID: ${{ secrets.MACOS_DEVELOPER_CERT_ID }}
run: |
security default-keychain -s signing_app.keychain
APP_PATH="build/bin/${{ env.ARTIFACT_NAME_PREFIX }}.app"
codesign --remove-signature "$APP_PATH"
codesign --remove-signature "$APP_PATH/Contents/MacOS/${{ env.ARTIFACT_NAME_PREFIX }}"
echo "Signing .app with App Certificate: $APP_CERTIFICATE"
# Sign the main executable
codesign --timestamp --options runtime -s "$APP_CERTIFICATE" --verbose "$APP_PATH/Contents/MacOS/${{ env.ARTIFACT_NAME_PREFIX }}"
# Sign the .app bundle
codesign --timestamp --deep --options runtime -s "$APP_CERTIFICATE" --force --verbose "$APP_PATH"
echo "Verifying Code Signature"
codesign --verify --verbose=4 "$APP_PATH"
- name: Install create-dmg
run: brew install create-dmg
- name: Create .dmg package
run: |
mkdir -p dist dmg_contents
cp -R "build/bin/${{ env.ARTIFACT_NAME_PREFIX }}.app" dmg_contents/
cp INSTALL_MACOS.md "dmg_contents/Installation Guide.md"
create-dmg \
--volname "${{ env.ARTIFACT_NAME_PREFIX }} Installer" \
--window-size 600 400 \
--app-drop-link 450 200 \
--icon "${{ env.ARTIFACT_NAME_PREFIX }}.app" 150 200 \
--icon "Installation Guide.md" 300 200 \
"dist/${{ env.ARTIFACT_NAME_PREFIX }}-$(git tag --sort=-version:refname | head -n 1).dmg" \
dmg_contents/
rm -rf dmg_contents
- name: Sign and Notarize DMG
env:
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_ID: [email protected]
APP_CERTIFICATE: ${{ secrets.MACOS_DEVELOPER_CERT_FULL_ID }}
APPLE_DEVELOPER_ID: ${{ secrets.MACOS_DEVELOPER_CERT_ID }}
run: |
DMG_PATH="dist/${{ env.ARTIFACT_NAME_PREFIX }}-$(git tag --sort=-version:refname | head -n 1).dmg"
echo "Signing .dmg with Certificate"
codesign --timestamp --deep --options runtime -s "$APP_CERTIFICATE" --force --verbose "$DMG_PATH"
echo "Submitting DMG for notarization"
xcrun notarytool submit "$DMG_PATH" \
--apple-id "$APPLE_ID" \
--password "$APPLE_PASSWORD" \
--team-id "$APPLE_DEVELOPER_ID" \
--wait
echo "Stapling notarization ticket"
xcrun stapler staple "$DMG_PATH"
echo "Verifying staple"
stapler validate "$DMG_PATH"
- name: Build Mac zip file
shell: bash
run: |
cd dist && zip "${{env.ARTIFACT_NAME_PREFIX}}-mac.zip" *.dmg
- name: Calculate ZIP SHA256
run: |
APP_VERSION=$(git tag --sort=-version:refname | head -n 1)
ZIP_PATH="dist/${{ env.ARTIFACT_NAME_PREFIX }}-mac.zip"
SHA256=$(shasum -a 256 "$ZIP_PATH" | awk '{print $1}')
echo "ZIP_SHA256=$SHA256" >> $GITHUB_ENV
echo "ZIP SHA256: $SHA256"
- name: Checkout Homebrew Tap
uses: actions/checkout@v4
with:
repository: scanoss/homebrew-dist
path: homebrew-dist
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
- name: Update Cask Formula
run: |
APP_VERSION=$(git tag --sort=-version:refname | head -n 1)
APP_VERSION=${APP_VERSION#v} # Remove 'v' prefix if present
sed -i '' \
-e "s/version \".*\"/version \"${APP_VERSION}\"/" \
-e "s/sha256 \".*\"/sha256 \"${ZIP_SHA256}\"/" \
homebrew-dist/Casks/scanoss-code-compare.rb
- name: Commit and Push Formula Update
run: |
cd homebrew-dist
git config user.name "SCANOSS Bot"
git config user.email "[email protected]"
git add Casks/scanoss-code-compare.rb
git commit -m "Update scanoss-code-compare to ${APP_VERSION}"
git push
- uses: actions/upload-artifact@v4
with:
name: artifact_m
path: |
dist/*.zip
build_linux:
name: Build for Linux
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
fetch-tags: true
# Setup and configure GoLang
- name: Setup GoLang
uses: actions/setup-go@v5
with:
check-latest: true
go-version: ${{ env.GOLANG_VERSION }}
- run: go version
shell: bash
# Setup and configure NodeJS
- name: Setup NodeJS
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
# Install Wails
- name: Install Wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
shell: bash
# Install Linux Wails deps and packaging tools
- name: Install Linux dependencies
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-0 libwebkit2gtk-4.0-dev gcc-aarch64-linux-gnu ruby ruby-dev rubygems build-essential rpm
sudo gem install --no-document fpm
shell: bash
# Build
- name: Build App
run: |
mkdir -p build/bin
cp -r assets build/assets
cp assets/appicon.png build
wails build -ldflags "-X github.com/scanoss/scanoss.cc/backend/entities.AppVersion=$(git tag --sort=-version:refname | head -n 1)" --platform linux/amd64 -o "${{ env.ARTIFACT_NAME_PREFIX }}-linux"
shell: bash
- name: Make binary executable
run: chmod +x "./build/bin/${{ env.ARTIFACT_NAME_PREFIX }}-linux"
shell: bash
- name: Prepare package files
run: |
APP_VERSION=$(git tag --sort=-version:refname | head -n 1)
# Create directory structure
mkdir -p staging/usr/local/lib/scanoss-cc
mkdir -p staging/usr/local/bin
mkdir -p staging/usr/share/applications
mkdir -p staging/usr/share/icons/hicolor/512x512/apps
# Copy binary and assets
cp "./build/bin/${{ env.ARTIFACT_NAME_PREFIX }}-linux" staging/usr/local/lib/scanoss-cc/scanoss-cc
cp -r build/assets staging/usr/local/lib/scanoss-cc/
cp build/appicon.png staging/usr/share/icons/hicolor/512x512/apps/scanoss-cc.png
# Copy wrapper script and desktop entry
cp .github/workflows/linux/scanoss-cc.wrapper staging/usr/local/bin/scanoss-cc
chmod +x staging/usr/local/bin/scanoss-cc
cp .github/workflows/linux/scanoss-cc.desktop staging/usr/share/applications/
- name: Create packages
run: |
APP_VERSION=$(git tag --sort=-version:refname | head -n 1)
APP_VERSION=${APP_VERSION#v} # Remove 'v' prefix if present
mkdir -p dist
# Create .deb package
fpm -C staging -s dir -t deb \
--name scanoss-cc \
--version "${APP_VERSION}" \
--architecture amd64 \
--description "SCANOSS Code Compare - GUI and CLI tool for quickly visualizing undeclared open source findings" \
--url "https://github.com/scanoss/scanoss.cc" \
--maintainer "SCANOSS" \
--depends libgtk-3-0 \
--depends libwebkit2gtk-4.0-37 \
--package "dist/scanoss-cc_${APP_VERSION}_amd64.deb"
# Create .rpm package
fpm -C staging -s dir -t rpm \
--name scanoss-cc \
--version "${APP_VERSION}" \
--architecture x86_64 \
--description "SCANOSS Code Compare - GUI and CLI tool for quickly visualizing undeclared open source findings" \
--url "https://github.com/scanoss/scanoss.cc" \
--maintainer "SCANOSS" \
--depends gtk3 \
--depends webkit2gtk3 \
--package "dist/scanoss-cc-${APP_VERSION}.x86_64.rpm"
- name: Upload to packagecloud.io
env:
PACKAGECLOUD_TOKEN: ${{ secrets.PACKAGECLOUD_TOKEN }}
run: |
APP_VERSION=$(git tag --sort=-version:refname | head -n 1)
# Install packagecloud CLI
gem install package_cloud
# Push .deb package
package_cloud push scanoss/scanoss-cc/debian/bullseye "dist/scanoss-cc_${APP_VERSION}_amd64.deb"
package_cloud push scanoss/scanoss-cc/ubuntu/focal "dist/scanoss-cc_${APP_VERSION}_amd64.deb"
package_cloud push scanoss/scanoss-cc/ubuntu/jammy "dist/scanoss-cc_${APP_VERSION}_amd64.deb"
# Push .rpm package
package_cloud push scanoss/scanoss-cc/el/8 "dist/scanoss-cc-${APP_VERSION}.x86_64.rpm"
package_cloud push scanoss/scanoss-cc/fedora/35 "dist/scanoss-cc-${APP_VERSION}.x86_64.rpm"
package_cloud push scanoss/scanoss-cc/fedora/36 "dist/scanoss-cc-${APP_VERSION}.x86_64.rpm"
- name: Create ZIP file
run: |
cd dist
cp ../INSTALL_LINUX.md "Installation Guide.md"
zip -r "${{ env.ARTIFACT_NAME_PREFIX }}-linux.zip" scanoss-cc_*.deb scanoss-cc-*.rpm "Installation Guide.md"
shell: bash
- name: Upload build assets
uses: actions/upload-artifact@v4
with:
name: artifact_l
path: dist/${{ env.ARTIFACT_NAME_PREFIX }}-linux.zip
build_w:
name: Build for Windows
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
fetch-tags: true
# Setup and configure GoLang
- name: Setup GoLang
uses: actions/setup-go@v5
with:
check-latest: true
go-version: ${{ env.GOLANG_VERSION }}
- run: go version
shell: bash
# Setup and configure Node JS
- name: Setup NodeJS
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
# Install Wails
- name: Install Wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
shell: bash
# Build
- name: Build App
run: |
mkdir -p build/bin
cp -r assets build/assets
cp assets/appicon.png build
wails build -ldflags "-X github.com/scanoss/scanoss.cc/backend/entities.AppVersion=$(git tag --sort=-version:refname | head -n 1)" --platform "windows/amd64" -webview2 download -o "${{ env.ARTIFACT_NAME_PREFIX }}-windows.exe"
shell: bash
- uses: actions/upload-artifact@v4
with:
name: artifact_w_unsigned
path: |
build/bin/${{ env.ARTIFACT_NAME_PREFIX }}*.exe
build_w_sign:
name: "Sign with CodeSignTool"
needs: [build_w]
runs-on: ubuntu-latest
steps:
- name: Download artifact W unsigned
uses: actions/download-artifact@v4
with:
name: artifact_w_unsigned
#This stage locates the unsigned .exe binary and move to win_unsigned folder.
#CodeSignTool does not support reading and writting into the same filepath
- name: Find Windows Artifact Path
id: win-path-artifact
run: |
# Use find to locate the exe file
WIN_BINARY_FILEPATH=$(find . -name "${{ env.ARTIFACT_NAME_PREFIX }}-windows.exe")
mkdir -p win_unsigned
mv "$WIN_BINARY_FILEPATH" win_unsigned/
echo "ARTIFACT_WIN_PATH=win_unsigned/$(basename "$WIN_BINARY_FILEPATH")" >> "$GITHUB_OUTPUT"
shell: bash
- name: Sign Windows Artifact with CodeSignTool
uses: sslcom/esigner-codesign@develop
env:
ARTIFACT_WIN_PATH: ${{ steps.win-path-artifact.outputs.ARTIFACT_WIN_PATH }}
with:
command: sign
username: ${{secrets.WINDOWS_CODE_SIGNING_TOOL_ES_USERNAME}}
password: ${{secrets.WINDOWS_CODE_SIGNING_TOOL_ES_PASSWORD}}
credential_id: ${{secrets.WINDOWS_CODE_SIGNING_TOOL_CREDENTIAL_ID}}
totp_secret: ${{secrets.WINDOWS_CODE_SIGNING_TOOL_ES_TOTP_SECRET}}
file_path: ${GITHUB_WORKSPACE}/${{ env.ARTIFACT_WIN_PATH }}
output_path: ${GITHUB_WORKSPACE}
- name: zip file
shell: bash
run: |
mkdir -p build/bin
cd win_unsigned
# Create zip from the current directory
zip -j "../build/bin/${{ env.ARTIFACT_NAME_PREFIX }}-win.zip" "${{ env.ARTIFACT_NAME_PREFIX }}-windows.exe"
- uses: actions/upload-artifact@v4
with:
name: artifact_w
path: |
build/bin/*.zip
create_release:
needs: [build_w_sign, build_mac, build_linux]
runs-on: ubuntu-latest
steps:
- name: Download artifact W
uses: actions/download-artifact@v4
with:
name: artifact_w
- name: Download artifact M
uses: actions/download-artifact@v4
with:
name: artifact_m
- name: Download artifact L
uses: actions/download-artifact@v4
with:
name: artifact_l
- name: Create Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Create an array of zip files
zip_files=()
while IFS= read -r -d '' file; do
zip_files+=("$file")
done < <(find . -name "*.zip" -print0)
# Create the release with all zip files
gh release create "${{ github.ref_name }}" \
--repo "${{ github.repository }}" \
--generate-notes \
--draft \
"${zip_files[@]}"
shell: bash