Skip to content

[SYNPY-1636] Add build scripts for minimal Synapse CLI and interactive commands #1227

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
285 changes: 200 additions & 85 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ jobs:

# if changing the below change the run-integration-tests versions and the check-deploy versions
# Make sure that we are running the integration tests on the first and last versions of the matrix
python: ['3.9', '3.10', '3.11', '3.12', '3.13']
# python: ['3.9', '3.10', '3.11', '3.12', '3.13']
python: ['3.13']

runs-on: ${{ matrix.os }}

Expand Down Expand Up @@ -102,96 +103,96 @@ jobs:
pip install numpy
fi

- name: run-unit-tests
shell: bash
run: |
pytest -sv --cov-append --cov=. --cov-report xml tests/unit
- name: Check for Secret availability
id: secret-check
if: ${{ contains(fromJSON('["3.9"]'), matrix.python) || contains(fromJSON('["3.13"]'), matrix.python) }}
# perform secret check & put boolean result as an output
shell: bash
run: |
if [ -z "${{ secrets.encrypted_d17283647768_key }}" ] || [ -z "${{ secrets.encrypted_d17283647768_iv }}" ]; then
echo "secrets_available=false" >> $GITHUB_OUTPUT;
else
echo "secrets_available=true" >> $GITHUB_OUTPUT;
fi

if [ -z "${{ secrets.synapse_personal_access_token }}" ]; then
echo "synapse_pat_available=false" >> $GITHUB_OUTPUT;
else
echo "synapse_pat_available=true" >> $GITHUB_OUTPUT;
fi
# - name: run-unit-tests
# shell: bash
# run: |
# pytest -sv --cov-append --cov=. --cov-report xml tests/unit
# - name: Check for Secret availability
# id: secret-check
# if: ${{ contains(fromJSON('["3.9"]'), matrix.python) || contains(fromJSON('["3.13"]'), matrix.python) }}
# # perform secret check & put boolean result as an output
# shell: bash
# run: |
# if [ -z "${{ secrets.encrypted_d17283647768_key }}" ] || [ -z "${{ secrets.encrypted_d17283647768_iv }}" ]; then
# echo "secrets_available=false" >> $GITHUB_OUTPUT;
# else
# echo "secrets_available=true" >> $GITHUB_OUTPUT;
# fi

# if [ -z "${{ secrets.synapse_personal_access_token }}" ]; then
# echo "synapse_pat_available=false" >> $GITHUB_OUTPUT;
# else
# echo "synapse_pat_available=true" >> $GITHUB_OUTPUT;
# fi

# run integration tests iff the decryption keys for the test configuration are available.
# they will not be available in pull requests from forks.
# run integration tests on the oldest and newest supported versions of python.
# we don't run on the entire matrix to avoid a 3xN set of concurrent tests against
# the target server where N is the number of supported python versions.
- name: run-integration-tests
shell: bash

# keep versions consistent with the first and last from the strategy matrix
if: ${{ (contains(fromJSON('["3.9"]'), matrix.python) || contains(fromJSON('["3.13"]'), matrix.python)) && steps.secret-check.outputs.secrets_available == 'true'}}
run: |
# decrypt the encrypted test synapse configuration
openssl aes-256-cbc -K ${{ secrets.encrypted_d17283647768_key }} -iv ${{ secrets.encrypted_d17283647768_iv }} -in test.synapseConfig.enc -out test.synapseConfig -d
mv test.synapseConfig ~/.synapseConfig

if [ "${{ startsWith(matrix.os, 'ubuntu') }}" == "true" ]; then
# on linux only we can build and run a docker container to serve as an SFTP host for our SFTP tests.
# Docker is not available on GH Action runners on Mac and Windows.

docker build -t sftp_tests - < tests/integration/synapseclient/core/upload/Dockerfile_sftp
docker run -d sftp_tests:latest

# get the internal IP address of the just launched container
export SFTP_HOST=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -q))

printf "[sftp://$SFTP_HOST]\nusername: test\npassword: test\n" >> ~/.synapseConfig

# add to known_hosts so the ssh connections can be made without any prompting/errors
mkdir -p ~/.ssh
ssh-keyscan -H $SFTP_HOST >> ~/.ssh/known_hosts
fi

# set env vars used in external bucket tests from secrets
export EXTERNAL_S3_BUCKET_NAME="${{secrets.EXTERNAL_S3_BUCKET_NAME}}"
export EXTERNAL_S3_BUCKET_AWS_ACCESS_KEY_ID="${{secrets.EXTERNAL_S3_BUCKET_AWS_ACCESS_KEY_ID}}"
export EXTERNAL_S3_BUCKET_AWS_SECRET_ACCESS_KEY="${{secrets.EXTERNAL_S3_BUCKET_AWS_SECRET_ACCESS_KEY}}"

# Set env vars for OTEL
export OTEL_EXPORTER_OTLP_ENDPOINT="${{ vars.OTEL_EXPORTER_OTLP_ENDPOINT }}"
export OTEL_SERVICE_INSTANCE_ID="${{ vars.OTEL_SERVICE_INSTANCE_ID }}"
export SYNAPSE_INTEGRATION_TEST_OTEL_ENABLED="${{ vars.SYNAPSE_INTEGRATION_TEST_OTEL_ENABLED }}"
export OTEL_EXPORTER_OTLP_HEADERS="${{ secrets.OTEL_EXPORTER_OTLP_HEADERS }}"

# Setup ignore patterns based on Python version
IGNORE_FLAGS="--ignore=tests/integration/synapseclient/test_command_line_client.py"

if [ "${{ matrix.python }}" == "3.9" ]; then
# For min Python version, ignore async tests
IGNORE_FLAGS="$IGNORE_FLAGS --ignore=tests/integration/synapseclient/models/async/"
echo "Running integration tests for Min Python version (3.9) - ignoring async tests"
elif [ "${{ matrix.python }}" == "3.13" ]; then
# For max Python version, ignore synchronous tests
IGNORE_FLAGS="$IGNORE_FLAGS --ignore=tests/integration/synapseclient/models/synchronous/"
echo "Running integration tests for Max Python version (3.13) - ignoring synchronous tests"
fi

# use loadscope to avoid issues running tests concurrently that share scoped fixtures
pytest -sv --reruns 3 --cov-append --cov=. --cov-report xml tests/integration -n 8 $IGNORE_FLAGS --dist loadscope

# Execute the CLI tests in a non-dist way because they were causing some test instability when being run concurrently
pytest -sv --reruns 3 --cov-append --cov=. --cov-report xml tests/integration/synapseclient/test_command_line_client.py
- name: Upload coverage report
id: upload_coverage_report
uses: actions/upload-artifact@v4
if: ${{ contains(fromJSON('["3.13"]'), matrix.python) && contains(fromJSON('["ubuntu-22.04"]'), matrix.os)}}
with:
name: coverage-report
path: coverage.xml
# - name: run-integration-tests
# shell: bash

# # keep versions consistent with the first and last from the strategy matrix
# if: ${{ (contains(fromJSON('["3.9"]'), matrix.python) || contains(fromJSON('["3.13"]'), matrix.python)) && steps.secret-check.outputs.secrets_available == 'true'}}
# run: |
# # decrypt the encrypted test synapse configuration
# openssl aes-256-cbc -K ${{ secrets.encrypted_d17283647768_key }} -iv ${{ secrets.encrypted_d17283647768_iv }} -in test.synapseConfig.enc -out test.synapseConfig -d
# mv test.synapseConfig ~/.synapseConfig

# if [ "${{ startsWith(matrix.os, 'ubuntu') }}" == "true" ]; then
# # on linux only we can build and run a docker container to serve as an SFTP host for our SFTP tests.
# # Docker is not available on GH Action runners on Mac and Windows.

# docker build -t sftp_tests - < tests/integration/synapseclient/core/upload/Dockerfile_sftp
# docker run -d sftp_tests:latest

# # get the internal IP address of the just launched container
# export SFTP_HOST=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -q))

# printf "[sftp://$SFTP_HOST]\nusername: test\npassword: test\n" >> ~/.synapseConfig

# # add to known_hosts so the ssh connections can be made without any prompting/errors
# mkdir -p ~/.ssh
# ssh-keyscan -H $SFTP_HOST >> ~/.ssh/known_hosts
# fi

# # set env vars used in external bucket tests from secrets
# export EXTERNAL_S3_BUCKET_NAME="${{secrets.EXTERNAL_S3_BUCKET_NAME}}"
# export EXTERNAL_S3_BUCKET_AWS_ACCESS_KEY_ID="${{secrets.EXTERNAL_S3_BUCKET_AWS_ACCESS_KEY_ID}}"
# export EXTERNAL_S3_BUCKET_AWS_SECRET_ACCESS_KEY="${{secrets.EXTERNAL_S3_BUCKET_AWS_SECRET_ACCESS_KEY}}"

# # Set env vars for OTEL
# export OTEL_EXPORTER_OTLP_ENDPOINT="${{ vars.OTEL_EXPORTER_OTLP_ENDPOINT }}"
# export OTEL_SERVICE_INSTANCE_ID="${{ vars.OTEL_SERVICE_INSTANCE_ID }}"
# export SYNAPSE_INTEGRATION_TEST_OTEL_ENABLED="${{ vars.SYNAPSE_INTEGRATION_TEST_OTEL_ENABLED }}"
# export OTEL_EXPORTER_OTLP_HEADERS="${{ secrets.OTEL_EXPORTER_OTLP_HEADERS }}"

# # Setup ignore patterns based on Python version
# IGNORE_FLAGS="--ignore=tests/integration/synapseclient/test_command_line_client.py"

# if [ "${{ matrix.python }}" == "3.9" ]; then
# # For min Python version, ignore async tests
# IGNORE_FLAGS="$IGNORE_FLAGS --ignore=tests/integration/synapseclient/models/async/"
# echo "Running integration tests for Min Python version (3.9) - ignoring async tests"
# elif [ "${{ matrix.python }}" == "3.13" ]; then
# # For max Python version, ignore synchronous tests
# IGNORE_FLAGS="$IGNORE_FLAGS --ignore=tests/integration/synapseclient/models/synchronous/"
# echo "Running integration tests for Max Python version (3.13) - ignoring synchronous tests"
# fi

# # use loadscope to avoid issues running tests concurrently that share scoped fixtures
# pytest -sv --reruns 3 --cov-append --cov=. --cov-report xml tests/integration -n 8 $IGNORE_FLAGS --dist loadscope

# # Execute the CLI tests in a non-dist way because they were causing some test instability when being run concurrently
# pytest -sv --reruns 3 --cov-append --cov=. --cov-report xml tests/integration/synapseclient/test_command_line_client.py
# - name: Upload coverage report
# id: upload_coverage_report
# uses: actions/upload-artifact@v4
# if: ${{ contains(fromJSON('["3.13"]'), matrix.python) && contains(fromJSON('["ubuntu-22.04"]'), matrix.os)}}
# with:
# name: coverage-report
# path: coverage.xml

sonarcloud:
needs: [test]
Expand Down Expand Up @@ -343,6 +344,120 @@ jobs:
# asset_content_type: application/zip


# build standalone desktop client artifacts for Windows and macOS on release
build-desktop-clients:
needs: [test, pre-commit]
# if: github.event_name == 'release'

strategy:
matrix:
include:
# Windows builds
- os: windows-2022
platform: windows
arch: x64
python-version: '3.11'
artifact-name: synapse-desktop-client-windows-x64

# macOS builds - Intel
- os: macos-13
platform: macos
arch: intel
python-version: '3.11'
artifact-name: synapse-desktop-client-macos-intel

# macOS builds - Apple Silicon (M1/M2)
- os: macos-14
platform: macos
arch: apple-silicon
python-version: '3.11'
artifact-name: synapse-desktop-client-macos-apple-silicon

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v4

- name: Install uv and set the python version
uses: astral-sh/setup-uv@v6
with:
activate-environment: true
python-version: 3.13

- name: Install py-dependencies
shell: bash
run: |
uv pip install -e ".[boto3,pandas,pysftp,tests]"
uv pip install pyinstaller

# ensure that numpy c extensions are installed on windows
# https://stackoverflow.com/a/59346525
if [ "${{startsWith(runner.os, 'Windows')}}" == "true" ]; then
uv pip uninstall numpy
uv pip uninstall setuptools
uv pip install setuptools
uv pip install numpy
fi

- name: Extract tag name
shell: bash
# TAG_NAME="${{ github.event.release.tag_name }}"
run: |
TAG_NAME="beta-01"
# Remove 'v' prefix if it exists
TAG_CLEAN=${TAG_NAME#v}
echo "TAG_CLEAN=$TAG_CLEAN" >> $GITHUB_ENV

- name: Build Windows Desktop Client
if: matrix.platform == 'windows'
shell: cmd
run: |
call build_windows_native_gui.bat %TAG_CLEAN%

- name: Build macOS Desktop Client
if: matrix.platform == 'macos'
shell: bash
run: |
chmod +x build.sh
./build.sh macos $TAG_CLEAN

- name: Prepare artifact (Windows)
if: matrix.platform == 'windows'
shell: bash
run: |
cd dist
ARTIFACT_FILE=$(ls synapse-desktop-client*.exe | head -n1)
FINAL_NAME="${{ matrix.artifact-name }}-${{ env.TAG_CLEAN }}.exe"
mv "$ARTIFACT_FILE" "$FINAL_NAME"
echo "ARTIFACT_PATH=dist/$FINAL_NAME" >> $GITHUB_ENV
echo "ARTIFACT_NAME=$FINAL_NAME" >> $GITHUB_ENV

- name: Prepare artifact (macOS)
if: matrix.platform == 'macos'
shell: bash
run: |
cd dist
ARTIFACT_FILE=$(ls synapse-desktop-client-macos* | head -n1)
FINAL_NAME="${{ matrix.artifact-name }}-${{ env.TAG_CLEAN }}"
mv "$ARTIFACT_FILE" "$FINAL_NAME"
echo "ARTIFACT_PATH=dist/$FINAL_NAME" >> $GITHUB_ENV
echo "ARTIFACT_NAME=$FINAL_NAME" >> $GITHUB_ENV

- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ env.ARTIFACT_PATH }}

# Commented out for testing - only upload to action run, not GitHub release
# - name: Upload to GitHub Release
# uses: softprops/action-gh-release@v1
# with:
# files: ${{ env.ARTIFACT_PATH }}
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


# re-download the built package to the appropriate pypi server.
# we upload prereleases to test.pypi.org and releases to pypi.org.
deploy:
Expand Down
Loading
Loading