Skip to content

Merge pull request #1556 from atsign-foundation/gitbook #198

Merge pull request #1556 from atsign-foundation/gitbook

Merge pull request #1556 from atsign-foundation/gitbook #198

Workflow file for this run

name: Multibuild
on:
push:
tags:
- "v*.*.*"
workflow_dispatch:
inputs:
main_build_only:
description: "Run non-dockerx builds only"
required: true
default: false
type: boolean
permissions: # added using https://github.com/step-security/secure-repo
contents: read
jobs:
verify_tags:
permissions:
contents: write # Needed to create workflow branch
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Create action branch
run: |
git config --global user.name 'Atsign Robot'
git config --global user.email '41898282+github-actions[bot]@users.noreply.github.com'
git checkout -b multibuild-${{github.run_number}}
- name:
Ensure pubspec.yaml matches git ref (if current git ref is a version
tag)
shell: bash
if: startsWith(github.ref, 'refs/tags/v')
working-directory: ./packages/dart/sshnoports
run: |
REF=${{ github.ref }}
VER=${REF:11}
sed -i "0,/version:/{s/version: \(.*\)/version: "${VER}"/}" pubspec.yaml
if [ "$(git status --porcelain)" ]; then
git add .
git commit -m 'ci: Updated version to tag'
fi
- name: Push changes to branch
run: git push --set-upstream origin multibuild-${{github.run_number}}
main_build:
needs: verify_tags
runs-on: ${{ matrix.os }}
defaults:
run:
working-directory: ./packages/dart/sshnoports
strategy:
matrix:
include:
- os: ubuntu-latest
output-name: sshnp-linux-x64
ext: ""
bundle: "shell"
- os: macos-13
output-name: sshnp-macos-x64
ext: ""
bundle: "shell"
- os: macos-14
output-name: sshnp-macos-arm64
ext: ""
bundle: "shell"
- os: windows-latest
output-name: sshnp-windows-x64
ext: ".exe"
bundle: "windows"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: multibuild-${{github.run_number}}
- uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 # v1.6.5
# create directories needed for build
- run: |
mkdir sshnp
mkdir tarball
- if: ${{ matrix.os != 'windows-latest' }}
run: mkdir sshnp/debug
# compile binaries
- run: |
dart pub get --enforce-lockfile
dart run build_runner build --delete-conflicting-outputs
dart compile exe bin/activate_cli.dart -v -o sshnp/at_activate${{ matrix.ext }}
dart compile exe bin/sshnp.dart -v -o sshnp/sshnp${{ matrix.ext }}
dart compile exe bin/npt.dart -v -o sshnp/npt${{ matrix.ext }}
dart compile exe bin/npp_file.dart -v -o sshnp/npa_file${{ matrix.ext }}
dart compile exe bin/npp_file.dart -v -o sshnp/npp_file${{ matrix.ext }}
dart compile exe bin/sshnpd.dart -v -o sshnp/sshnpd${{ matrix.ext }}
dart compile exe bin/srv.dart -v -o sshnp/srv${{ matrix.ext }}
dart compile exe bin/npp_atserver.dart -v -o sshnp/npp_atserver${{ matrix.ext }}
- name: build admin API
working-directory: ./apps/admin/admin_api
run: |
dart pub get --enforce-lockfile
dart compile exe bin/np_admin.dart -v -o ../../../packages/dart/sshnoports/sshnp/np_admin${{ matrix.ext }}
- if: ${{ matrix.os != 'windows-latest' }}
run: |
dart compile exe bin/srvd.dart -v -o sshnp/srvd${{ matrix.ext }}
dart compile exe bin/srvd.dart -D ENABLE_SNOOP=true -v -o sshnp/debug/srvd${{ matrix.ext }}
# copy additional bundle items to build
- run: |
cp -r bundles/core/* sshnp/
cp -r bundles/${{ matrix.bundle }}/* sshnp/
cp LICENSE sshnp
# codesign for apple
- if: ${{ matrix.os == 'macos-13' || matrix.os == 'macos-14' }}
name: Import certificates
env:
MACOS_CODESIGN_CERT: ${{ secrets.MACOS_CODESIGN_CERT }}
MACOS_CODESIGN_CERT_PASSWORD:
${{ secrets.MACOS_CODESIGN_CERT_PASSWORD }}
MACOS_SIGNING_IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY }}
MACOS_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }}
run: |
# Load certificate
CERT_PATH=$RUNNER_TEMP/noports-codesign.p12
echo -n "$MACOS_CODESIGN_CERT" | base64 --decode -o $CERT_PATH
# create temp keychain
KEYCHAIN_PATH=$RUNNER_TEMP/build.keychain
security create-keychain -p "$MACOS_KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security default-keychain -s $KEYCHAIN_PATH
security unlock-keychain -p "$MACOS_KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security import $CERT_PATH -k $KEYCHAIN_PATH -P "$MACOS_CODESIGN_CERT_PASSWORD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:apple,:,codesign: -s -k "$MACOS_KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# codesign
/usr/bin/codesign \
--force \
-s "$MACOS_SIGNING_IDENTITY" \
--options=runtime \
--entitlements ./tools/templates/entitlements.plist \
--prefix "com.atsign." \
--timestamp \
-v \
sshnp/{sshnp,sshnpd,srv,srvd,at_activate,debug/srvd,npt,npa_file,npp_file,npp_atserver,np_admin}
# zip the build
- if: ${{ matrix.os == 'macos-13' || matrix.os == 'macos-14' }}
run:
ditto -c -k --keepParent sshnp tarball/${{ matrix.output-name }}.zip
- if: ${{ matrix.os == 'ubuntu-latest' }}
run: tar -cvzf tarball/${{ matrix.output-name }}.tgz sshnp
- if: ${{ matrix.os == 'windows-latest' }}
run:
Compress-Archive -Path sshnp -Destination tarball/${{
matrix.output-name }}.zip
# notarize the build
- if: ${{ matrix.os == 'macos-13' || matrix.os == 'macos-14' }}
env:
MACOS_APPLE_ID: ${{ secrets.MACOS_APPLE_ID }}
MACOS_TEAM_ID: ${{ secrets.MACOS_TEAM_ID }}
MACOS_APPLE_ID_PASSWORD: ${{ secrets.MACOS_APPLE_ID_PASSWORD }}
run: |
xcrun notarytool submit tarball/${{ matrix.output-name }}.zip \
--apple-id "$MACOS_APPLE_ID" \
--team-id "$MACOS_TEAM_ID" \
--password "$MACOS_APPLE_ID_PASSWORD" \
--wait
# upload the build
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name:
${{ matrix.output-name
}}-${{github.ref_name}}-${{github.run_number}}-${{github.run_attempt}}
path: ./packages/dart/sshnoports/tarball
if-no-files-found: error
other_build:
needs: verify_tags
runs-on: ubuntu-latest
strategy:
matrix:
# platform: [linux/arm/v7, linux/arm64, linux/riscv64]
platform: [linux/arm/v7, linux/arm64]
include:
- platform: linux/arm/v7
output-name: sshnp-linux-arm
- platform: linux/arm64
output-name: sshnp-linux-arm64
# - platform: linux/riscv64
# output-name: sshnp-linux-riscv64
steps:
- if: ${{ ! inputs.main_build_only }}
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: multibuild-${{github.run_number}}
- if: ${{ ! inputs.main_build_only }}
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
- if: ${{ ! inputs.main_build_only }}
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
- if: ${{ ! inputs.main_build_only }}
run: |
docker buildx build -t atsigncompany/sshnptarball -f ./tools/multibuild/Dockerfile.package \
--platform ${{ matrix.platform }} -o type=tar,dest=bins.tar .
mkdir tarballs
tar -xvf bins.tar -C tarballs
- if: ${{ ! inputs.main_build_only }}
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name:
${{ matrix.output-name
}}-${{github.ref_name}}-${{github.run_number}}-${{github.run_attempt}}
path: ./tarballs/${{ matrix.output-name }}.tgz
if-no-files-found: error
web_build:
needs: verify_tags
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: multibuild-${{github.run_number}}
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: '20.17.0'
# setup required npm version
- run: |
npm install -g [email protected]
# create directory needed for build
- name: build admin webapp
working-directory: ./apps/admin/webapp
run: |
mkdir -p sshnp/web/admin
mkdir tarball
npm ci
npm run build
cp -r dist/* sshnp/web/admin/
tar -cvzf tarball/sshnp-web-admin-noarch.tgz sshnp
# upload the build
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name:
sshnp-web-admin-noarch-${{github.ref_name}}-${{github.run_number
}}-${{github.run_attempt}}
path: ./apps/admin/webapp/tarball
if-no-files-found: error
universal_sh:
if: startsWith(github.ref, 'refs/tags/v')
defaults:
run:
working-directory: ./packages/dart/sshnoports/bundles
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- run: |
write_metadata() {
start_line="# SCRIPT METADATA"
end_line="# END METADATA"
file=$1
variable=$2
value=$3
# since this is linux only, sed -i is safe without a file ext.
sed -i "/$start_line/,/$end_line/s|$variable=\".*\"|$variable=\"$value\"|g" "$file"
}
REF=${{ github.ref }}
TAG=${REF:11}
write_metadata universal.sh sshnp_version "$TAG"
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: universal.sh-${{github.ref_name}}-${{github.run_number}}-${{github.run_attempt}}
path: ./packages/dart/sshnoports/bundles/universal.sh
if-no-files-found: error
universal_ps1:
if: startsWith(github.ref, 'refs/tags/v')
defaults:
run:
working-directory: ./packages/dart/sshnoports/bundles
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: universal.ps1-${{github.ref_name}}-${{github.run_number}}-${{github.run_attempt}}
path: ./packages/dart/sshnoports/bundles/universal.ps1
if-no-files-found: error
github-release:
name: >-
Upload artifacts and generate SBOMs and checksums for provenance
needs: [main_build, other_build, web_build, universal_sh, universal_ps1]
runs-on: ubuntu-latest
outputs:
hashes: ${{ steps.hash.outputs.hashes }}
permissions:
contents: write # Mandatory for making GitHub Releases
id-token: write # Mandatory for sigstore
attestations: write
steps:
- name: Checkout pubspec.lock
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
sparse-checkout: packages/dart/sshnoports/pubspec.lock
sparse-checkout-cone-mode: false
- name: Download all the tarballs
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
path: tarballs/
- name: Generate SBOM
uses: sbomify/github-action@a04e82ca42a0d9e6bdb57a2cb1a8978e96b4f45c # v0.3.0
env:
TOKEN: ${{ secrets.SBOMIFY_TOKEN }}
COMPONENT_ID: '-93khk8pUi'
LOCK_FILE: './packages/dart/sshnoports/pubspec.lock'
SBOM_VERSION: ${{github.ref_name}}
OUTPUT_FILE: 'tarballs/noports_dart-${{github.ref_name}}-sbom.cdx.json'
AUGMENT: true
ENRICH: true
UPLOAD: true
- name: Move packages for signing
run: |
cd tarballs
mv */*.sh .
mv */*.ps1 .
mv */*.tgz .
mv */*.zip .
rm -Rf -- */
- name: Generate SHA256 checksums
working-directory: tarballs
run: sha256sum * > checksums.txt
- name: Upload artifacts to GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
# Upload to GitHub Release using the `gh` CLI.
# `tarballs/` contains the built packages, and the
# sbomify produced SBOMs
run: >-
gh release upload '${{ github.ref_name }}' tarballs/** --repo '${{
github.repository }}'
- id: hash
name: Pass artifact hashes for SLSA provenance
working-directory: tarballs
run: |
echo "hashes=$(cat checksums.txt | base64 -w0)" >> "$GITHUB_OUTPUT"
- uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1.4.4
with:
subject-path: "tarballs/**"
provenance:
needs: [github-release]
permissions:
actions: read # Needed for detection of GitHub Actions environment.
id-token: write # Needed for provenance signing and ID
contents: write # Needed for release uploads
uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected] # 5a775b367a56d5bd118a224a811bba288150a563
with:
base64-subjects: "${{ needs.github-release.outputs.hashes }}"
upload-assets: true
cleanup:
name: Clean up temporary branch
needs: [main_build, other_build]
runs-on: ubuntu-latest
permissions:
contents: write # Needed to delete workflow branch
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: multibuild-${{github.run_number}}
- name: Delete workflow branch
run: git push origin --delete multibuild-${{github.run_number}}
notify_on_completion:
needs: [github-release, cleanup]
runs-on: ubuntu-latest
steps:
- name: Google Chat Notification
uses: Co-qn/google-chat-notification@3691ccf4763537d6e544bc6cdcccc1965799d056 # v1
with:
name:
SSH no ports binaries were built by GitHub Action ${{
github.run_number }}
url: ${{ secrets.GOOGLE_CHAT_WEBHOOK }}
status: ${{ job.status }}
notify_on_failure:
if: failure()
needs: [github-release, cleanup]
runs-on: ubuntu-latest
steps:
- name: Google Chat Notification
uses: Co-qn/google-chat-notification@3691ccf4763537d6e544bc6cdcccc1965799d056 # v1
with:
name:
SSH no ports binaries build by GitHub Action ${{ github.run_number
}}
url: ${{ secrets.GOOGLE_CHAT_WEBHOOK }}
status: failure