diff --git a/.github/actions/setup-muse2-main/action.yml b/.github/actions/setup-muse2-main/action.yml new file mode 100644 index 0000000..c27c394 --- /dev/null +++ b/.github/actions/setup-muse2-main/action.yml @@ -0,0 +1,32 @@ +name: Setup MUSE2 from main +description: Build and configure MUSE2_PATH from the MUSE2 main branch via cargo install +inputs: + muse2_exe: + description: MUSE2 executable name for the current OS + required: true +runs: + using: composite + steps: + - name: Install Rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@v1 + + - name: Build and install MUSE2 from main (cargo) + shell: bash + run: | + cargo install \ + --git https://github.com/EnergySystemsModellingLab/MUSE2 \ + --branch main \ + --root "$GITHUB_WORKSPACE/muse2_cargo_root" + + - name: Set MUSE2_PATH (Linux / macOS) + if: runner.os == 'Linux' || runner.os == 'macOS' + shell: bash + run: | + echo "MUSE2_PATH=${{ github.workspace }}/muse2_cargo_root/bin/${{ inputs.muse2_exe }}" >> "$GITHUB_ENV" + + - name: Set MUSE2_PATH (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + $exePath = "${{ github.workspace }}\muse2_cargo_root\bin\${{ inputs.muse2_exe }}" + echo "MUSE2_PATH=$exePath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append diff --git a/.github/actions/setup-muse2-release/action.yml b/.github/actions/setup-muse2-release/action.yml new file mode 100644 index 0000000..30b39b6 --- /dev/null +++ b/.github/actions/setup-muse2-release/action.yml @@ -0,0 +1,55 @@ +name: Setup MUSE2 from latest release +description: Download latest MUSE2 release asset for current OS and configure MUSE2_PATH +inputs: + github_token: + description: GitHub token for API access + required: true + muse2_exe: + description: MUSE2 executable name for the current OS + required: true +runs: + using: composite + steps: + - name: Get latest MUSE2 release tag + id: muse2_release + shell: bash + run: | + TAG=$(curl -sSf \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ inputs.github_token }}" \ + https://api.github.com/repos/EnergySystemsModellingLab/MUSE2/releases/latest \ + | jq -r '.tag_name') + + if [[ -z "$TAG" || "$TAG" == "null" ]]; then + echo "::error::Failed to retrieve latest MUSE2 release tag." + exit 1 + fi + + echo "Resolved latest MUSE2 release: $TAG" + echo "tag=$TAG" >> "$GITHUB_OUTPUT" + + - name: Download MUSE2 release asset + shell: bash + run: | + curl -sSfL \ + "https://github.com/EnergySystemsModellingLab/MUSE2/releases/download/${{ steps.muse2_release.outputs.tag }}/${{ runner.os == 'Windows' && 'muse2_windows.zip' || runner.os == 'macOS' && 'muse2_macos_arm.tar.gz' || 'muse2_linux.tar.gz' }}" \ + --output "muse2_asset_download" + + - name: Extract and set MUSE2_PATH (Linux / macOS) + if: runner.os == 'Linux' || runner.os == 'macOS' + shell: bash + run: | + mkdir -p muse2_bin + tar -xf muse2_asset_download -C muse2_bin + chmod +x "muse2_bin/${{ inputs.muse2_exe }}" + echo "MUSE2_PATH=${{ github.workspace }}/muse2_bin/${{ inputs.muse2_exe }}" >> "$GITHUB_ENV" + + - name: Extract and set MUSE2_PATH (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + New-Item -ItemType Directory -Force -Path muse2_bin | Out-Null + Rename-Item -Path "muse2_asset_download" -NewName "muse2_asset_download.zip" + Expand-Archive -Path "muse2_asset_download.zip" -DestinationPath muse2_bin -Force + $exePath = "${{ github.workspace }}\muse2_bin\${{ inputs.muse2_exe }}" + echo "MUSE2_PATH=$exePath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append diff --git a/.github/actions/verify-muse2/action.yml b/.github/actions/verify-muse2/action.yml new file mode 100644 index 0000000..21d5c7b --- /dev/null +++ b/.github/actions/verify-muse2/action.yml @@ -0,0 +1,24 @@ +name: Verify MUSE2 installation +description: Validate that MUSE2_PATH points to an executable file for the current OS +runs: + using: composite + steps: + - name: Verify MUSE2_PATH (Linux / macOS) + if: runner.os == 'Linux' || runner.os == 'macOS' + shell: bash + run: | + if [[ ! -f "$MUSE2_PATH" ]]; then + echo "::error::MUSE2 executable not found at: $MUSE2_PATH" + exit 1 + fi + echo "MUSE2_PATH is set to: $MUSE2_PATH" + + - name: Verify MUSE2_PATH (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + if (-not (Test-Path -Path $env:MUSE2_PATH -PathType Leaf)) { + Write-Error "MUSE2 executable not found at: $env:MUSE2_PATH" + exit 1 + } + Write-Host "MUSE2_PATH is set to: $env:MUSE2_PATH" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 15418a4..cb08688 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: Test and build +name: Test against MUSE2 on: push: branches: [main] @@ -7,114 +7,16 @@ on: workflow_call: jobs: - test: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - os: ubuntu-latest - python-version: '3.14' - muse2_asset: muse2_linux.tar.gz - muse2_exe: muse2 - - os: windows-latest - python-version: '3.14' - muse2_asset: muse2_windows.zip - muse2_exe: muse2.exe - - os: macos-latest - python-version: '3.14' - muse2_asset: muse2_macos_arm.tar.gz - muse2_exe: muse2 - - steps: - - uses: actions/checkout@v6 - - - uses: astral-sh/setup-uv@v7 - with: - enable-cache: true - prune-cache: false - activate-environment: true - python-version: ${{ matrix.python-version }} - - - name: Install dependencies - run: uv sync - - # Query the GitHub API for the latest MUSE2 release tag (e.g. "v2.0.0"). - # The tag is written to GITHUB_OUTPUT so subsequent steps can reference it. - - name: Get latest MUSE2 release tag - id: muse2_release - shell: bash - run: | - TAG=$(curl -sSf \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${{ github.token }}" \ - https://api.github.com/repos/EnergySystemsModellingLab/MUSE2/releases/latest \ - | jq -r '.tag_name') - - if [[ -z "$TAG" || "$TAG" == "null" ]]; then - echo "::error::Failed to retrieve latest MUSE2 release tag." - exit 1 - fi - - echo "Resolved latest MUSE2 release: $TAG" - echo "tag=$TAG" >> "$GITHUB_OUTPUT" - - # Download the platform-appropriate MUSE2 release asset. - # 'shell: bash' is used on all platforms - - name: Download MUSE2 release asset - shell: bash - run: | - curl -sSfL \ - "https://github.com/EnergySystemsModellingLab/MUSE2/releases/download/${{ steps.muse2_release.outputs.tag }}/${{ matrix.muse2_asset }}" \ - --output "muse2_asset_download" - - - name: Extract MUSE2 and set environment variable (Linux / macOS) - if: runner.os == 'Linux' || runner.os == 'macOS' - shell: bash - run: | - mkdir -p muse2_bin - tar -xf muse2_asset_download -C muse2_bin - chmod +x "muse2_bin/${{ matrix.muse2_exe }}" - echo "MUSE2_PATH=${{ github.workspace }}/muse2_bin/${{ matrix.muse2_exe }}" >> "$GITHUB_ENV" - - - name: Extract MUSE2 and set environment variable (Windows) - if: runner.os == 'Windows' - shell: pwsh - run: | - New-Item -ItemType Directory -Force -Path muse2_bin | Out-Null - Rename-Item -Path "muse2_asset_download" -NewName "muse2_asset_download.zip" - Expand-Archive -Path "muse2_asset_download.zip" -DestinationPath muse2_bin -Force - $exePath = "${{ github.workspace }}\muse2_bin\${{ matrix.muse2_exe }}" - echo "MUSE2_PATH=$exePath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - # Confirm the muse2 executable is present and the environment variable is set correctly. - - name: Verify MUSE2 installation (Linux / macOS) - if: runner.os == 'Linux' || runner.os == 'macOS' - shell: bash - run: | - if [[ ! -f "$MUSE2_PATH" ]]; then - echo "::error::MUSE2 executable not found at: $MUSE2_PATH" - exit 1 - fi - echo "MUSE2_PATH is set to: $MUSE2_PATH" - - - name: Verify MUSE2 installation (Windows) - if: runner.os == 'Windows' - shell: pwsh - run: | - if (-not (Test-Path -Path $env:MUSE2_PATH -PathType Leaf)) { - Write-Error "MUSE2 executable not found at: $env:MUSE2_PATH" - exit 1 - } - Write-Host "MUSE2_PATH is set to: $env:MUSE2_PATH" - - - name: Run tests - run: pytest - - - name: Upload coverage to Codecov - if: runner.os == 'Linux' - uses: codecov/codecov-action@v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./coverage.xml - fail_ci_if_error: true + test_release: + name: Latest MUSE2 release + uses: ./.github/workflows/test-with-muse2.yml + with: + muse2_source: release + secrets: inherit + + test_main: + name: Current MUSE2 main branch + uses: ./.github/workflows/test-with-muse2.yml + with: + muse2_source: main + secrets: inherit diff --git a/.github/workflows/test-with-muse2.yml b/.github/workflows/test-with-muse2.yml new file mode 100644 index 0000000..5c14416 --- /dev/null +++ b/.github/workflows/test-with-muse2.yml @@ -0,0 +1,71 @@ +name: Test with MUSE2 + +on: + workflow_call: + inputs: + muse2_source: + description: Which MUSE2 source to test against (release or main) + required: true + type: string + secrets: + CODECOV_TOKEN: + required: false + +jobs: + test: + name: Run Pytest + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + python-version: '3.14' + muse2_exe: muse2 + - os: windows-latest + python-version: '3.14' + muse2_exe: muse2.exe + - os: macos-latest + python-version: '3.14' + muse2_exe: muse2 + + steps: + - uses: actions/checkout@v6 + + - uses: astral-sh/setup-uv@v7 + with: + enable-cache: true + prune-cache: false + activate-environment: true + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: uv sync + + - name: Setup MUSE2 from main + if: inputs.muse2_source == 'main' + uses: ./.github/actions/setup-muse2-main + with: + muse2_exe: ${{ matrix.muse2_exe }} + + - name: Setup MUSE2 from latest release + if: inputs.muse2_source == 'release' + uses: ./.github/actions/setup-muse2-release + with: + github_token: ${{ github.token }} + muse2_exe: ${{ matrix.muse2_exe }} + + - name: Verify MUSE2 installation + uses: ./.github/actions/verify-muse2 + + - name: Run tests + run: pytest + + - name: Upload coverage to Codecov + # Latest linux release only - they should all be the same + if: runner.os == 'Linux' && inputs.muse2_source == 'release' + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ./coverage.xml + fail_ci_if_error: true