Modify how we generate sbom files #108
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Package python parsec | |
on: | |
workflow_call: | |
inputs: | |
version: | |
description: The version to use | |
type: string | |
required: true | |
workflow_dispatch: | |
inputs: | |
version: | |
description: The version to use (if not provided will generated one from the codespace version) | |
type: string | |
required: false | |
pull_request: | |
paths: | |
- .github/workflows/package-python.yml | |
- packaging/** | |
- build.py | |
- pyproject.toml | |
# We set `concurrency` to prevent having this workflow being run on code that is not up-to-date on a PR (a user make multiple push in a quick manner). | |
# But on the main branch, we don't want that behavior. | |
# Having the workflow run on each merge commit is something we would like, that could help us where a regression was made and missed by previous checks. | |
# | |
# For that we use `head_ref` that is only defined on `pull-request` and fallback to `run_id` (this is a counter, so it's value is unique between workflow call). | |
concurrency: | |
group: package-python-${{ github.workflow }}-${{ github.head_ref || github.run_id }} | |
cancel-in-progress: true | |
env: | |
node-version: 18.12.0 | |
python-version: 3.9 | |
poetry-version: 1.3.2 | |
# Cargo will be faster with this configuration. | |
# It will only update it's index for the dependencies that we use. | |
# https://blog.rust-lang.org/2023/03/09/Rust-1.68.0.html#cargos-sparse-protocol | |
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse | |
permissions: | |
contents: read | |
jobs: | |
package-wheel: | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- name: 🐧 Linux | |
platform: linux | |
os: ubuntu-22.04 | |
- name: 🍎 macOS | |
platform: macos | |
os: macos-12 | |
- name: 🏁 Windows | |
platform: windows | |
os: windows-2022 | |
name: "${{ matrix.name }}: 📦 Packaging (build Wheel)" | |
runs-on: ${{ matrix.os }} | |
outputs: | |
wheel-version: ${{ steps.version.outputs.full }} | |
steps: | |
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # pin v3.5.2 | |
timeout-minutes: 5 | |
- uses: ./.github/actions/setup-python-poetry | |
with: | |
python-version: ${{ env.python-version }} | |
poetry-version: ${{ env.poetry-version }} | |
timeout-minutes: 10 | |
- name: Get wheel version | |
id: version | |
shell: bash | |
run: | | |
set -eux | |
function parse_version { | |
PYTHONPATH=. python3 misc/releaser.py version "$@" | |
} | |
if [ -n "${{ inputs.version }}" ]; then | |
parse_version "${{ inputs.version }}" | tee -a $GITHUB_OUTPUT | |
else | |
case "${{ github.event_name }}" in | |
workflow_call) | |
echo "The top workflow should have provided the version to use" | |
exit 2 | |
;; | |
workflow_dispatch) | |
# No version provided, fallback to the version in the repository | |
parse_version --uniq-dev | tee -a $GITHUB_OUTPUT | |
;; | |
pull_request) | |
parse_version --uniq-dev | tee -a $GITHUB_OUTPUT | |
;; | |
*) | |
echo 'Unsupported event type ${{ github.event_name }}' >&2 | |
exit 1 | |
;; | |
esac | |
fi | |
- name: Set parsec version ${{ steps.version.outputs.full }} | |
run: python3 misc/version_updater.py --tool parsec --version ${{ steps.version.outputs.full }} | |
- name: Build wheel | |
uses: pypa/cibuildwheel@51f5c7fe68ff24694d5a6ac0eb3ad476ddd062a8 # pin v2.13.0 | |
with: | |
output-dir: dist | |
timeout-minutes: 50 | |
- name: Set file for wheel version | |
run: echo v${{ steps.version.outputs.full }} > dist/version | |
- name: Hack the wheel macos version | |
if: startsWith(matrix.os, 'macos-') | |
shell: bash | |
run: | | |
set -eux | |
# Old wheel name | |
OLD_WHEEL_NAME=$(basename dist/parsec_cloud-*.whl) | |
# Unzip the wheel | |
mkdir temp | |
cd temp | |
unzip ../dist/$OLD_WHEEL_NAME | |
# Get platform new wheel name | |
python -m pip install wheel | |
PLATFORM=$(python -c "from wheel.bdist_wheel import get_platform; print(get_platform('.'))") | |
NEW_WHEEL_NAME=$(basename ../dist/parsec_cloud-*.whl | sed "s/macosx_.*_x86_64/$PLATFORM/") | |
# Update archive and zip back | |
sed -i "" "s/macosx_.*_x86_64/$PLATFORM/" parsec_cloud-*.dist-info/WHEEL | |
zip -r $NEW_WHEEL_NAME * | |
cd .. | |
# Replace old wheel with the new one | |
mv temp/$NEW_WHEEL_NAME dist/ | |
rm dist/$OLD_WHEEL_NAME | |
rm -rf temp | |
- name: Generate requirements & constraints infos | |
run: python packaging/wheel/wheel_it.py . --output dist --skip-wheel | |
# Install syft | |
- uses: taiki-e/install-action@8984d603c208823d3c1a1b796f4081736f3ae3f9 # pin v2.11.6 | |
with: | |
tool: [email protected] | |
- name: Generate SBOM | |
run: syft scan --config=.syft.yaml --output=spdx-json=dist/Parsec-SBOM-${{ matrix.platform }}-Wheel.spdx.json --output=cyclonedx-json=dist/Parsec-SBOM-${{ matrix.platform }}-Wheel.cyclonedx.json . | |
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # pin v3.1.2 | |
with: | |
name: ${{ runner.os }}-${{ runner.arch }}-wheel | |
path: dist/ | |
if-no-files-found: error | |
timeout-minutes: 5 | |
package-linux-build-snap: | |
name: "🐧 Linux: 📦 Packaging (build Snap)" | |
needs: package-wheel | |
runs-on: ubuntu-20.04 | |
env: | |
WHEEL_VERSION: ${{ needs.package-wheel.outputs.wheel-version }} | |
steps: | |
- name: Install snapcraft | |
run: sudo snap install snapcraft --classic | |
- name: Debug snapcraft version | |
run: | | |
set -e | |
echo "::warning title=Snapcraft Version::using $(snapcraft --version)" | |
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # pin v3.5.2 | |
timeout-minutes: 5 | |
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # pin v3.0.2 | |
with: | |
name: ${{ runner.os }}-${{ runner.arch }}-wheel | |
path: dist | |
- name: List downloaded artifacts | |
run: tree dist | |
- name: Copy snap build configuration | |
working-directory: ${{ runner.temp }} | |
run: | | |
cp -Rv ${{ github.workspace }}/packaging/snap/{bin,snap} . | |
- name: Copy wheel configuration + python requirement | |
working-directory: ${{ runner.temp }} | |
run: | | |
mkdir src | |
WHEEL=$(ls -1 ${{ github.workspace }}/dist/parsec_cloud-*.whl) | |
cp -Rv $WHEEL src/ | |
cp -v ${{ github.workspace }}/dist/core-requirements.txt src/ | |
- name: Set snap build version | |
run: | | |
# Sed with a range specifier to only match on line 2 (where the version value is expected to be). | |
sed -i.back '2,/^version:/{s/^version: .*$/version: v${{ env.WHEEL_VERSION }}/}' ${{ runner.temp }}/snap/snapcraft.yaml | |
diff -u ${{ runner.temp }}/snap/snapcraft.yaml{.back,} || true | |
# Use grep as sanity check to ensure that we have the expected version value. | |
grep --line-number --fixed-string 'version: v${{ env.WHEEL_VERSION }}' ${{ runner.temp }}/snap/snapcraft.yaml | |
- name: Run snapcraft | |
working-directory: ${{ runner.temp }} | |
run: snapcraft --destructive-mode | |
# Install syft | |
- uses: taiki-e/install-action@8984d603c208823d3c1a1b796f4081736f3ae3f9 # pin v2.11.6 | |
with: | |
tool: [email protected] | |
- name: Generate SBOM | |
run: syft scan --config=.syft.yaml --output=spdx-json=${{ runner.temp }}/Parsec-SBOM-linux-snap.spdx.json --output=cyclonedx-json=${{ runner.temp }}/Parsec-SBOM-linux-snap.cyclonedx.json . | |
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # pin v3.1.2 | |
with: | |
name: ${{ runner.os }}-${{ runner.arch }}-snap | |
path: | | |
${{ runner.temp }}/parsec*.snap | |
${{ runner.temp }}/Parsec-SBOM-linux-snap.spdx.json | |
${{ runner.temp }}/Parsec-SBOM-linux-snap.cyclonedx.json | |
if-no-files-found: error | |
package-linux-test-snap: | |
name: "🐧 Linux: 📦 Packaging (test Snap on ${{ matrix.os }})" | |
needs: package-linux-build-snap | |
runs-on: ${{ matrix.os }} | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ ubuntu-20.04, ubuntu-22.04 ] | |
steps: | |
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # pin v3.0.2 | |
with: | |
name: ${{ runner.os }}-${{ runner.arch }}-snap | |
path: dist | |
- name: Install Snapcraft | |
uses: samuelmeuli/action-snapcraft@d33c176a9b784876d966f80fb1b461808edc0641 # pin v2.1.1 | |
- name: Never trust a Snap | |
run: | | |
set -eux | |
sudo snap install --classic --dangerous dist/parsec*.snap | |
parsec.cli --version | |
parsec.cli --help | |
# Make sure snap contains core but not backend | |
MODULES_NOT_AVAILABLE=$(parsec.cli --help | grep -i "not available") | |
test "$(echo $MODULES_NOT_AVAILABLE | grep -i 'backend')" | |
test -z "$(echo $MODULES_NOT_AVAILABLE | grep -i 'core')" | |
xvfb-run parsec --diagnose | |
package-windows-build-installer-content: | |
name: "🏁 Windows: 📦 Packaging (build installer content)" | |
needs: package-wheel | |
runs-on: windows-2022 | |
env: | |
WHEEL_VERSION: ${{ needs.package-wheel.outputs.wheel-version }} | |
steps: | |
- uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0 # pin v4.6.1 | |
with: | |
python-version: ${{ env.python-version }} | |
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # pin v3.5.2 | |
timeout-minutes: 5 | |
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # pin v3.0.2 | |
with: | |
name: ${{ runner.os }}-${{ runner.arch }}-wheel | |
path: dist | |
- name: List downloaded artifacts | |
run: Get-ChildItem -Recurse -Path dist | |
- uses: microsoft/setup-msbuild@1ff57057b5cfdc39105cd07a01d78e9b0ea0c14c # pin v1.3.1 | |
- name: Build Icon overlays COM objects | |
run: msbuild -maxCpuCount -property:Configuration=Release .\windows-icon-handler\windows-icon-handler.sln | |
shell: cmd | |
- name: Prepare build directory | |
run: Copy-Item -Recurse -Path ${{ github.workspace }}\packaging\windows\* -Destination ${{ runner.temp }} | |
working-directory: ${{ runner.temp }} | |
- name: Debug ${{ runner.temp }} dir | |
run: Get-ChildItem -Recurse -Path ${{ runner.temp }} | |
- name: Freeze Parsec | |
run: python3 freeze_program.py ${{ github.workspace }} --wheel-it-dir ${{ github.workspace }}/dist | |
working-directory: ${{ runner.temp }} | |
- name: Debug build directory | |
run: Get-ChildItem -Path ${{ runner.temp }}\build | |
- name: Test start generated exe | |
shell: bash | |
run: ./build/parsec-*/parsec.exe --diagnose | |
working-directory: ${{ runner.temp }} | |
# Cannot do the NSIS installer part in CI given it requires to sign `parsec.exe` | |
- name: Artifact name | |
id: names | |
shell: bash | |
run: echo "archive=parsec-unsigned-v${{ env.WHEEL_VERSION }}-raw-windows-installer.zip" >> $GITHUB_OUTPUT | |
# The 7z man can be found here <https://linux.die.net/man/1/7z> | |
- name: Prepare artifact | |
run: | | |
md dist | |
cd build | |
# cspell:disable-next-line | |
7z a -tzip ..\${{ steps.names.outputs.archive }} ` | |
manifest.ini ` | |
install_files.nsh ` | |
uninstall_files.nsh ` | |
parsec-* ` | |
winfsp-* | |
working-directory: ${{ runner.temp }} | |
# Install syft | |
- uses: taiki-e/install-action@8984d603c208823d3c1a1b796f4081736f3ae3f9 # pin v2.11.6 | |
with: | |
tool: [email protected] | |
- name: Generate SBOM | |
run: syft scan --config=.syft.yaml --output=spdx-json=${{ runner.temp }}/Parsec-SBOM-windows-app.spdx.json --output=cyclonedx-json=${{ runner.temp }}/Parsec-SBOM-windows-app.cyclonedx.json . | |
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # pin v3.1.2 | |
with: | |
name: ${{ runner.os }}-${{ runner.arch }}-installer | |
path: | | |
${{ runner.temp }}/${{ steps.names.outputs.archive }} | |
${{ runner.temp }}/Parsec-SBOM-windows-app.spdx.json | |
${{ runner.temp }}/Parsec-SBOM-windows-app.cyclonedx.json | |
if-no-files-found: error | |
package-macos-build-app: | |
runs-on: macos-12 | |
name: "🍎 macOS: 📦 Packaging (build installer content)" | |
needs: package-wheel | |
env: | |
WHEEL_VERSION: ${{ needs.package-wheel.outputs.wheel-version }} | |
steps: | |
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # pin v3.5.2 | |
timeout-minutes: 5 | |
- uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0 # pin v4.6.1 | |
id: setup-python | |
with: | |
python-version: ${{ env.python-version }} | |
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # pin v3.0.2 | |
with: | |
name: ${{ runner.os }}-${{ runner.arch }}-wheel | |
path: dist | |
- name: List downloaded artifacts | |
run: ls -lR dist | |
- name: Copy packaging script | |
run: cp -Rv ${{ github.workspace }}/packaging/macOS/* ${{ runner.temp }} | |
- name: Freeze Parsec | |
run: python freeze_program.py ${{ github.workspace }} --wheel-it-dir ${{ github.workspace }}/dist | |
working-directory: ${{ runner.temp }} | |
- name: Debug ${{ runner.temp }} dir | |
run: ls -lR ${{ runner.temp }} | |
- name: Generate Parsec.app | |
run: > | |
tar --verbose --create --bzip2 | |
--file parsec-unsigned-v${{ env.WHEEL_VERSION }}-macos-amd64.tar.bz2 | |
--directory build/pyinstaller_dist parsec.app | |
working-directory: ${{ runner.temp }} | |
# Install syft | |
- uses: taiki-e/install-action@8984d603c208823d3c1a1b796f4081736f3ae3f9 # pin v2.11.6 | |
with: | |
tool: [email protected] | |
- name: Generate SBOM | |
run: syft scan --config=.syft.yaml --output=spdx-json=${{ runner.temp }}/Parsec-SBOM-macos-app.spdx.json --output=cyclonedx-json=${{ runner.temp }}/Parsec-SBOM-macos-app.cyclonedx.json . | |
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # pin v3.1.2 | |
with: | |
name: ${{ runner.os }}-${{ runner.arch }}-installer | |
path: | | |
${{ runner.temp }}/parsec-unsigned-v${{ env.WHEEL_VERSION }}-macos-amd64.tar.bz2 | |
${{ runner.temp }}/Parsec-SBOM-macos-app.spdx.json | |
${{ runner.temp }}/Parsec-SBOM-macos-app.cyclonedx.json | |
if-no-files-found: error | |
package-macos-test-app: | |
runs-on: macos-${{ matrix.macos-version }} | |
name: "🍎 macOS: 📦 Packaging (test app on macOS-${{ matrix.macos-version }})" | |
needs: [ package-wheel, package-macos-build-app ] | |
env: | |
WHEEL_VERSION: ${{ needs.package-wheel.outputs.wheel-version }} | |
strategy: | |
fail-fast: false | |
matrix: | |
macos-version: [ 11, 12 ] | |
steps: | |
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # pin v3.0.2 | |
with: | |
name: ${{ runner.os }}-${{ runner.arch }}-installer | |
path: dist | |
# The lsregister call forces the app's entry in the Launch Services database. Otherwise the error | |
# 'kLSNoExecutableErr: The executable is missing' might be raised. | |
- name: Test open app | |
run: | | |
set -eux | |
tar -xzvf dist/parsec-unsigned-v${{ env.WHEEL_VERSION }}-macos-amd64.tar.bz2 # cspell:disable-line | |
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f parsec.app | |
open parsec.app --args --diagnose | |
package-android-app: | |
# We currently disable android building, this job need to be updated to work with `vite`. | |
# See tracking issue #4395 & #4419 | |
if: false | |
runs-on: ubuntu-22.04 | |
name: 🤖 Package Android app | |
env: | |
NDK_VERSION: 23.2.8568313 | |
SDK_VERSION: 30.0.3 | |
steps: | |
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # pin v3.5.2 | |
timeout-minutes: 5 | |
- name: Add rustup targets | |
run: rustup target add armv7-linux-androideabi i686-linux-android aarch64-linux-android x86_64-linux-android | |
timeout-minutes: 5 | |
- name: Configure Runner environment | |
run: | | |
echo "$ANDROID_HOME/cmdline-tools/latest/bin" > $GITHUB_PATH | |
- name: Install dependencies for Android | |
run: sdkmanager --install "ndk;${{ env.NDK_VERSION }}" "build-tools;${{ env.SDK_VERSION }}" | |
- name: Install dependencies for ionic project | |
run: npm clean-install | |
working-directory: oxidation/client | |
- name: Build ionic for Android | |
run: | | |
npm run android:copy:release | |
working-directory: oxidation/client | |
- name: Build apk | |
run: bash ./gradlew assembleRelease | |
working-directory: oxidation/client/android | |
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # pin v3.1.2 | |
with: | |
name: unsigned-android-app | |
path: | | |
oxidation/client/android/app/build/outputs/apk/release/app-release-unsigned.apk | |
oxidation/client/android/app/build/outputs/apk/release/output-metadata.json | |
if-no-files-found: error |