diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5ace460..6cc0071 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,3 +4,5 @@ updates: directory: "/" schedule: interval: "weekly" + cooldown: + default-days: 7 diff --git a/.github/workflows/benchmark-impl.yml b/.github/workflows/benchmark-impl.yml index 86ab211..8ac9129 100644 --- a/.github/workflows/benchmark-impl.yml +++ b/.github/workflows/benchmark-impl.yml @@ -58,20 +58,20 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.ref }} persist-credentials: false - name: Set up python ${{ matrix.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python-version }} - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry with: version: ${{ inputs.poetry-version }} - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: benchmark version: ${{ matrix.python-version }} @@ -83,12 +83,15 @@ jobs: - name: Set up variables id: vars run: | - echo "timeit=benchmark_make_workflow_${{ matrix.num_elements }}_elements-${{ runner.os }}-py-${{ matrix.python-version }}.txt" >> $GITHUB_OUTPUT + echo "timeit=benchmark_make_workflow_${N_ELEMS}_elements-${RUNNER_OS}-py-${PY_VER}.txt" >> $GITHUB_OUTPUT shell: bash + env: + N_ELEMS: ${{ matrix.num_elements }} + PY_VER: ${{ matrix.python-version }} - name: Run app make workflow command run: | - poetry run $EXECUTABLE --timeit-file $TIMEIT_FILE make $BENCHMARK --var N $N_ELEMS + poetry run "$EXECUTABLE" --timeit-file "$TIMEIT_FILE" make $BENCHMARK --var N "$N_ELEMS" env: EXECUTABLE: ${{ inputs.executable_name }} BENCHMARK: ${{ inputs.benchmark_make_workflow }} @@ -97,7 +100,7 @@ jobs: shell: bash - name: Store benchmark file - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ steps.vars.outputs.timeit }} path: ${{ steps.vars.outputs.timeit }} @@ -113,17 +116,17 @@ jobs: run: | mkdir benchmarks - name: Fetch benchmark data - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: merge-multiple: true path: benchmarks - name: Delete partial benchmark data - uses: geekyeggo/delete-artifact@v6 + uses: geekyeggo/delete-artifact@176a747ab7e287e3ff4787bf8a148716375ca118 # v6.0.0 with: name: "*" failOnError: false - name: Store benchmark data archive - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 id: upload with: name: benchmarks diff --git a/.github/workflows/build-exes-impl.yml b/.github/workflows/build-exes-impl.yml index e4dc422..590998c 100644 --- a/.github/workflows/build-exes-impl.yml +++ b/.github/workflows/build-exes-impl.yml @@ -142,14 +142,14 @@ jobs: sha: ${{ steps.info.outputs.sha }} steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 # get all history and tags persist-credentials: false - name: Get executable version name and store git SHA id: info run: | - CUR_TAG=$(git describe --tags $(git rev-list --tags --max-count=1)) + CUR_TAG="$(git describe --tags $(git rev-list --tags --max-count=1))" echo "CUR_TAG is: $CUR_TAG" echo "cur_tag=$CUR_TAG" >> $GITHUB_OUTPUT vers=$(git describe --tags) @@ -167,23 +167,23 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ needs.status.outputs.sha }} persist-credentials: false - name: Set up python - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ inputs.python-version }} - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry with: version: ${{ inputs.poetry-version }} - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: test version: ${{ inputs.python-version }} @@ -195,20 +195,28 @@ jobs: - name: Set data dir # in case we have a custom tag to use if: inputs.config_data_dir != '' run: | - poetry run ${{ inputs.executable_name }} config set data_dir ${{ inputs.config_data_dir }} + poetry run "$EXE_NAME" config set data_dir "$Dir" + env: + EXE_NAME: ${{ inputs.executable_name }} + Dir: ${{ inputs.config_data_dir }} - name: Set program dir # in case we have a custom tag to use if: inputs.config_program_dir != '' run: | - poetry run ${{ inputs.executable_name }} config set program_dir ${{ inputs.config_program_dir }} + poetry run "$EXE_NAME" config set program_dir "$Dir" + env: + EXE_NAME: ${{ inputs.executable_name }} + Dir: ${{ inputs.config_program_dir }} - name: Cache all app data and programs run: | - poetry run ${{ inputs.executable_name }} manage cache-all + poetry run "$EXE_NAME" manage cache-all + env: + EXE_NAME: ${{ inputs.executable_name }} - name: Upload all cached app data/programs id: upload-cached-app-data - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.executable_name }}-app-data-cache path: ~/.cache/${{ inputs.executable_name }} @@ -225,34 +233,34 @@ jobs: runs-on: windows-latest steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Setup tmate session if: inputs.tmate_debugging == 'true' - uses: mxschmitt/action-tmate@v3 + uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23 with: detached: true - name: Set up python ${{ inputs.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ inputs.python-version }} - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: build-exe version: ${{ inputs.python-version }} - name: Download prepared cached app data - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ inputs.executable_name }}-app-data-cache path: ${{ inputs.executable_name }}-app-data-cache - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry with: version: ${{ inputs.poetry-version }} @@ -262,26 +270,34 @@ jobs: - name: Configure the app's Python environment # this allows us to run integration tests that use `script_data_in/out: "direct"` id: configure_python_env run: | - poetry run ${{ inputs.executable_name }} env setup python --use-current - $result = (poetry run ${{ inputs.executable_name }} env info source_file -l python) + poetry run "$env:EXE_NAME" env setup python --use-current + $result = (poetry run "$env:EXE_NAME" env info source_file -l python) "env_source_file=$result" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8 + env: + EXE_NAME: ${{ inputs.executable_name }} - name: Build with pyinstaller for Windows (file) id: win_onefile if: inputs.build_onefile == 'true' working-directory: ${{ inputs.pyinstaller_dir }} - run: ./make.ps1 -ExeName "${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win" -LogLevel ${{ inputs.logLevel }} -BuildType 'onefile' + run: ./make.ps1 -ExeName "$env:EXE_NAME" -LogLevel "env:LOG_LEVEL" -BuildType 'onefile' + env: + EXE_NAME: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win + LOG_LEVEL: ${{ inputs.logLevel }} - name: Build with pyinstaller for Windows (folder) id: win_onedir if: inputs.build_onedir == 'true' working-directory: ${{ inputs.pyinstaller_dir }} - run: ./make.ps1 -ExeName "${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win-dir" -LogLevel ${{ inputs.logLevel }} -BuildType 'onedir' + run: ./make.ps1 -ExeName "$env:EXE_NAME" -LogLevel "$env:LOG_LEVEL" -BuildType 'onedir' + env: + EXE_NAME: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win-dir + LOG_LEVEL: ${{ inputs.logLevel }} - name: Upload executable artifact (file) id: upload-file if: steps.win_onefile.outcome == 'success' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win.exe path: ${{ inputs.pyinstaller_dir }}/dist/onefile/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win.exe @@ -290,7 +306,7 @@ jobs: - name: Upload executable artifact (folder) id: upload-folder if: steps.win_onedir.outcome == 'success' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win-dir path: ${{ inputs.pyinstaller_dir }}/dist/onedir/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win-dir @@ -298,7 +314,7 @@ jobs: - name: Upload spec file if: steps.win_onefile.outcome == 'success' || steps.win_onedir.outcome == 'success' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win.spec path: ${{ inputs.pyinstaller_dir }}/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win.spec @@ -306,7 +322,7 @@ jobs: - name: Upload build directory if: steps.win_onefile.outcome == 'success' || steps.win_onedir.outcome == 'success' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win-build path: ${{ inputs.pyinstaller_dir }}/build/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win @@ -315,11 +331,12 @@ jobs: - name: Install cached app data env: PYTHONUTF8: 1 + EXE_NAME: ${{ inputs.executable_name }} run: | - poetry run ${{ inputs.executable_name }} data install-cache ${{ inputs.executable_name }}-app-data-cache/data - poetry run ${{ inputs.executable_name }} data --list - poetry run ${{ inputs.executable_name }} program install-cache ${{ inputs.executable_name }}-app-data-cache/programs - poetry run ${{ inputs.executable_name }} program --list + poetry run $env:EXE_NAME data install-cache "$($env:EXE_NAME)-app-data-cache/data" + poetry run $env:EXE_NAME data --list + poetry run $env:EXE_NAME program install-cache "$(env:EXE_NAME)-app-data-cache/programs" + poetry run $env:EXE_NAME program --list - name: Run test suite on the frozen app (file) if: steps.win_onefile.outcome == 'success' && inputs.unit_tests == 'true' @@ -327,8 +344,11 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} PYTHONUNBUFFERED: ok PYTHONUTF8: 1 + EXE_FILE: ${{ inputs.pyinstaller_dir }}/dist/onefile/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win.exe + ENV_SRC: ${{ steps.configure_python_env.outputs.env_source_file }} + ARGS: ${{ inputs.unit_test_args }} run: | - ${{ inputs.pyinstaller_dir }}/dist/onefile/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win.exe test --with-env-source ${{ steps.configure_python_env.outputs.env_source_file }} ${{ inputs.unit_test_args }} + "$env:EXE_FILE" test --with-env-source "$env:ENV_SRC" $env:ARGS - name: Run test suite on the frozen app (folder) if: steps.win_onedir.outcome == 'success' && inputs.unit_tests == 'true' @@ -336,8 +356,11 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} PYTHONUNBUFFERED: ok PYTHONUTF8: 1 + EXE_FILE: ${{ inputs.pyinstaller_dir }}/dist/onedir/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win-dir/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win-dir.exe + ENV_SRC: ${{ steps.configure_python_env.outputs.env_source_file }} + ARGS: ${{ inputs.unit_test_args }} run: | - ${{ inputs.pyinstaller_dir }}/dist/onedir/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win-dir/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win-dir.exe test --with-env-source ${{ steps.configure_python_env.outputs.env_source_file }} ${{ inputs.unit_test_args }} + "$env:EXE_FILE" test --with-env-source "$env:ENV_SRC" $env:ARGS - name: Run integration test suite on the frozen app (file) # tests are more likely to fail in the one-file build than the one-dir build, so just run integration tests with the one-file build if: steps.win_onefile.outcome == 'success' && inputs.integration_tests == 'true' @@ -345,8 +368,11 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} PYTHONUNBUFFERED: ok PYTHONUTF8: 1 + EXE_FILE: ${{ inputs.pyinstaller_dir }}/dist/onefile/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win.exe + ENV_SRC: ${{ steps.configure_python_env.outputs.env_source_file }} + ARGS: ${{ inputs.integration_test_args }} run: | - ${{ inputs.pyinstaller_dir }}/dist/onefile/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-win.exe test --with-env-source ${{ steps.configure_python_env.outputs.env_source_file }} ${{ inputs.integration_test_args }} --integration + "$env:EXE_FILE" test --with-env-source "$env:ENV_SRC" $env:ARGS --integration macos: name: Build macOS Executables @@ -359,34 +385,34 @@ jobs: runs-on: macos-latest steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Setup tmate session if: inputs.tmate_debugging == 'true' - uses: mxschmitt/action-tmate@v3 + uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23 with: detached: true - name: Set up python ${{ inputs.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ inputs.python-version }} - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: build-exe version: ${{ inputs.python-version }} - name: Download prepared cached app data - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ inputs.executable_name }}-app-data-cache path: ${{ inputs.executable_name }}-app-data-cache - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry with: version: ${{ inputs.poetry-version }} @@ -396,26 +422,34 @@ jobs: - name: Configure the app's Python environment # this allows us to run integration tests that use `script_data_in/out: "direct"` id: configure_python_env run: | - poetry run ${{ inputs.executable_name }} env setup python --use-current - result=$(poetry run ${{ inputs.executable_name }} env info source_file -l python) + poetry run "$EXE_NAME" env setup python --use-current + result=$(poetry run "$EXE_NAME" env info source_file -l python) echo "env_source_file=$result" >> "$GITHUB_OUTPUT" + env: + EXE_NAME: ${{ inputs.executable_name }} - name: Build with pyinstaller for macOS (file) id: mac_onefile if: inputs.build_onefile == 'true' working-directory: ${{ inputs.pyinstaller_dir }} - run: ./make.sh ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS ${{ inputs.logLevel }} 'onefile' + run: ./make.sh "$TARGET" "$LOG_LEVEL" 'onefile' + env: + TARGET: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS + LOG_LEVEL: ${{ inputs.logLevel }} - name: Build with pyinstaller for macOS (folder) id: mac_onedir if: inputs.build_onedir == 'true' working-directory: ${{ inputs.pyinstaller_dir }} - run: ./make.sh ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS-dir ${{ inputs.logLevel }} 'onedir' + run: ./make.sh "$TARGET" "$LOG_LEVEL" 'onedir' + env: + TARGET: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS-dir + LOG_LEVEL: ${{ inputs.logLevel }} - name: Upload executable artifact (file) id: upload-file if: steps.mac_onefile.outcome == 'success' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS path: ${{ inputs.pyinstaller_dir }}/dist/onefile/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS @@ -424,7 +458,7 @@ jobs: - name: Upload executable artifact (folder) id: upload-folder if: steps.mac_onedir.outcome == 'success' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS-dir path: ${{ inputs.pyinstaller_dir }}/dist/onedir/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS-dir @@ -432,7 +466,7 @@ jobs: - name: Upload spec file if: steps.mac_onefile.outcome == 'success' || steps.mac_onedir.outcome == 'success' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS.spec path: ${{ inputs.pyinstaller_dir }}/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS.spec @@ -440,7 +474,7 @@ jobs: - name: Upload build directory if: steps.mac_onefile.outcome == 'success' || steps.mac_onedir.outcome == 'success' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS-build path: ${{ inputs.pyinstaller_dir }}/build/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS @@ -448,34 +482,45 @@ jobs: - name: Install cached app data run: | - poetry run ${{ inputs.executable_name }} data install-cache ${{ inputs.executable_name }}-app-data-cache/data - poetry run ${{ inputs.executable_name }} data --list - poetry run ${{ inputs.executable_name }} program install-cache ${{ inputs.executable_name }}-app-data-cache/programs - poetry run ${{ inputs.executable_name }} program --list + poetry run "$EXE_NAME" data install-cache "${EXE_NAME}-app-data-cache/data" + poetry run "$EXE_NAME" data --list + poetry run "$EXE_NAME" program install-cache "${EXE_NAME}-app-data-cache/programs" + poetry run "$EXE_NAME" program --list + env: + EXE_NAME: ${{ inputs.executable_name }} - name: Run test suite on the frozen app (file) if: steps.mac_onefile.outcome == 'success' && inputs.unit_tests == 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} PYTHONUNBUFFERED: ok + TARGET: ${{ inputs.pyinstaller_dir }}/dist/onefile/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS + ENV_SRC: ${{ steps.configure_python_env.outputs.env_source_file }} + UT_ARGS: ${{ inputs.unit_test_args }} run: | - ${{ inputs.pyinstaller_dir }}/dist/onefile/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS test --with-env-source ${{ steps.configure_python_env.outputs.env_source_file }} ${{ inputs.unit_test_args }} + "$TARGET" test --with-env-source "$ENV_SRC" $UT_ARGS - name: Run test suite on the frozen app (folder) if: steps.mac_onedir.outcome == 'success' && inputs.unit_tests == 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} PYTHONUNBUFFERED: ok + TARGET: ${{ inputs.pyinstaller_dir }}/dist/onedir/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS-dir/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS-dir + ENV_SRC: ${{ steps.configure_python_env.outputs.env_source_file }} + UT_ARGS: ${{ inputs.unit_test_args }} run: | - ${{ inputs.pyinstaller_dir }}/dist/onedir/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS-dir/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS-dir test --with-env-source ${{ steps.configure_python_env.outputs.env_source_file }} ${{ inputs.unit_test_args }} + "$TARGET" test --with-env-source "$ENV_SRC" $UT_ARGS - name: Run integration test suite on the frozen app (file) # tests are more likely to fail in the one-file build than the one-dir build, so just run integration tests with the one-file build if: steps.mac_onefile.outcome == 'success' && inputs.integration_tests == 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} PYTHONUNBUFFERED: ok + TARGET: ${{ inputs.pyinstaller_dir }}/dist/onefile/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS + ENV_SRC: ${{ steps.configure_python_env.outputs.env_source_file }} + IT_ARGS: ${{ inputs.integration_test_args }} run: | - ${{ inputs.pyinstaller_dir }}/dist/onefile/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-macOS test --with-env-source ${{ steps.configure_python_env.outputs.env_source_file }} ${{ inputs.integration_test_args }} --integration + "$TARGET" test --with-env-source "$ENV_SRC" $IT_ARGS --integration linux: name: Build Linux (Rocky Linux 8) Executables @@ -488,24 +533,24 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Setup tmate session if: inputs.tmate_debugging == 'true' - uses: mxschmitt/action-tmate@v3 + uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23 with: detached: true - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: build-exe version: ${{ inputs.python-version }} - name: Download prepared cached app data - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ inputs.executable_name }}-app-data-cache path: ${{ inputs.executable_name }}-app-data-cache @@ -518,18 +563,23 @@ jobs: - name: Build executable (file) within Docker id: linux_onefile if: inputs.build_onefile == 'true' - uses: addnab/docker-run-action@v3 + uses: $/run-in-docker with: - image: ghcr.io/hpcflow/rockylinux8-python:latest # most of the options are just so we can debug (via tmate) when we have a custom pytest --basetemp directory options: | -v ${{ github.workspace }}:/home - -u ${{ steps.user.outputs.user }} + -u $THE_USER --env HOME=/home --env XDG_DATA_HOME=/home/.local/share --env XDG_CACHE_HOME=/home/.cache - --env GH_TOKEN=${{ secrets.GITHUB_TOKEN }} - --env UNIT_TESTS=${{ inputs.unit_tests }} - --env INTEGRATION_TESTS=${{ inputs.integration_tests }} + --env GH_TOKEN + --env UNIT_TESTS + --env INTEGRATION_TESTS + --env PYINST_DIR + --env EXE_NAME + --env VER + --env LOG_LEVEL + --env UT_ARGS + --env IT_ARGS run: | set -e # exit on first failure @@ -540,42 +590,57 @@ jobs: # Configure the app's Python environment # this allows us to run integration tests that use `script_data_in/out: "direct"` - poetry run ${{ inputs.executable_name }} env setup python --use-current - ENV_SOURCE_FILE=$(poetry run ${{ inputs.executable_name }} env info source_file -l python) + poetry run "$EXE_NAME" env setup python --use-current + ENV_SOURCE_FILE=$(poetry run "$EXE_NAME" env info source_file -l python) echo "ENV_SOURCE_FILE=${ENV_SOURCE_FILE}" # build with pyinstaller for Rocky Linux (file) - cd ${{ inputs.pyinstaller_dir }} - ./make.sh ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-linux ${{ inputs.logLevel }} onefile + cd "$PYINST_DIR" + ./make.sh "${EXE_NAME}-${VER}-linux" "$LOG_LEVEL" onefile cd .. # install cache data - poetry run ${{ inputs.executable_name }} data install-cache ${{ inputs.executable_name }}-app-data-cache/data - poetry run ${{ inputs.executable_name }} data --list - poetry run ${{ inputs.executable_name }} program install-cache ${{ inputs.executable_name }}-app-data-cache/programs - poetry run ${{ inputs.executable_name }} program --list + poetry run "$PYINST_DIR" data install-cache "${EXE_NAME}-app-data-cache/data" + poetry run "$PYINST_DIR" data --list + poetry run "$PYINST_DIR" program install-cache "${EXE_NAME}-app-data-cache/programs" + poetry run "$PYINST_DIR" program --list export PYTHONUNBUFFERED=ok if [ "$UNIT_TESTS" = "true" ]; then # run test suite on the frozen app (file) - ${{ inputs.pyinstaller_dir }}/dist/onefile/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-linux test --with-env-source ${ENV_SOURCE_FILE} ${{ inputs.unit_test_args }} + "$PYINST_DIR/dist/onefile/${EXE_NAME}-${VER}-linux" test --with-env-source ${ENV_SOURCE_FILE} $UT_ARGS fi if [ "$INTEGRATION_TESTS" == "true" ]; then # run integration test suite on the frozen app (file) # tests are more likely to fail in the one-file build than the one-dir build, so just run integration tests with the one-file build - ${{ inputs.pyinstaller_dir }}/dist/onefile/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-linux test --with-env-source ${ENV_SOURCE_FILE} ${{ inputs.integration_test_args }} --integration + "$PYINST_DIR/dist/onefile/${EXE_NAME}-${VER}-linux" test --with-env-source ${ENV_SOURCE_FILE} $IT_ARGS --integration fi + env: + PYINST_DIR: ${{ inputs.pyinstaller_dir }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + UNIT_TESTS: ${{ inputs.unit_tests }} + INTEGRATION_TESTS: ${{ inputs.integration_tests }} + EXE_NAME: ${{ inputs.executable_name }} + VER: ${{ needs.status.outputs.version }} + LOG_LEVEL: ${{ inputs.logLevel }} + UT_ARGS: ${{ inputs.unit_test_args }} + IT_ARGS: ${{ inputs.integration_test_args }} + THE_USER: ${{ steps.user.outputs.user }} - name: Build executable (folder) within Docker id: linux_onedir if: inputs.build_onedir == 'true' - uses: addnab/docker-run-action@v3 + uses: $/run-in-docker with: - image: ghcr.io/hpcflow/rockylinux8-python:latest options: | -v ${{ github.workspace }}:/home - --env GH_TOKEN=${{ secrets.GITHUB_TOKEN }} + --env GH_TOKEN + --env EXE_NAME + --env LOG_LEVEL + --env PYINST_DIR + --env VER + --env UT_ARGS run: | set -e # exit on first failure @@ -586,31 +651,38 @@ jobs: # Configure the app's Python environment # this allows us to run integration tests that use `script_data_in/out: "direct"` - poetry run ${{ inputs.executable_name }} env setup python --use-current - ENV_SOURCE_FILE=$(poetry run ${{ inputs.executable_name }} env info source_file -l python) + poetry run "$EXE_NAME" env setup python --use-current + ENV_SOURCE_FILE=$(poetry run "$EXE_NAME" env info source_file -l python) echo "ENV_SOURCE_FILE=${ENV_SOURCE_FILE}" # build with pyinstaller for Rocky Linux (folder) - cd ${{ inputs.pyinstaller_dir }} - ./make.sh ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-linux-dir ${{ inputs.logLevel }} onedir + cd "$PYINST_DIR" + ./make.sh "${EXE_NAME}-${VER}-linux-dir" "$LOG_LEVEL" onedir cd .. # install cache data - poetry run ${{ inputs.executable_name }} data install-cache ${{ inputs.executable_name }}-app-data-cache/data - poetry run ${{ inputs.executable_name }} data --list - poetry run ${{ inputs.executable_name }} program install-cache ${{ inputs.executable_name }}-app-data-cache/programs - poetry run ${{ inputs.executable_name }} program --list + poetry run "$EXE_NAME" data install-cache "${EXE_NAME}-app-data-cache/data" + poetry run "$EXE_NAME" data --list + poetry run "$EXE_NAME" program install-cache "${EXE_NAME}-app-data-cache/programs" + poetry run "$EXE_NAME" program --list export PYTHONUNBUFFERED=ok if [ "$UNIT_TESTS" == "true" ]; then # run test suite on the frozen app (folder) - ${{ inputs.pyinstaller_dir }}/dist/onedir/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-linux-dir/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-linux-dir test --with-env-source ${ENV_SOURCE_FILE} ${{ inputs.unit_test_args }} + "${PYINST_DIR}/dist/onedir/${EXE_NAME}-${VER}-linux-dir/${EXE_NAME}-${VER}-linux-dir" test --with-env-source ${ENV_SOURCE_FILE} $UT_ARGS fi + env: + PYINST_DIR: ${{ inputs.pyinstaller_dir }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + EXE_NAME: ${{ inputs.executable_name }} + LOG_LEVEL: ${{ inputs.logLevel }} + VER: ${{ needs.status.outputs.version }} + UT_ARGS: ${{ inputs.unit_test_args }} - name: Upload executable artifact (file) id: upload-file if: steps.linux_onefile.outcome == 'success' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-linux path: ${{ inputs.pyinstaller_dir }}/dist/onefile/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-linux @@ -619,7 +691,7 @@ jobs: - name: Upload executable artifact (folder) id: upload-folder if: steps.linux_onedir.outcome == 'success' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-linux-dir path: ${{ inputs.pyinstaller_dir }}/dist/onedir/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-linux-dir @@ -627,7 +699,7 @@ jobs: - name: Upload spec file if: steps.linux_onefile.outcome == 'success' || steps.linux_onedir.outcome == 'success' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-linux.spec path: ${{ inputs.pyinstaller_dir }}/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-linux.spec @@ -635,7 +707,7 @@ jobs: - name: Upload build directory if: steps.linux_onefile.outcome == 'success' || steps.linux_onedir.outcome == 'success' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-linux-build path: ${{ inputs.pyinstaller_dir }}/build/${{ inputs.executable_name }}-${{ needs.status.outputs.version }}-linux @@ -649,7 +721,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Delete cache artifact - uses: geekyeggo/delete-artifact@v6 + uses: geekyeggo/delete-artifact@176a747ab7e287e3ff4787bf8a148716375ca118 # v6.0.0 with: name: "*-app-data-cache" failOnError: false diff --git a/.github/workflows/doc-build-impl.yml b/.github/workflows/doc-build-impl.yml index 51dfc35..f823a3c 100644 --- a/.github/workflows/doc-build-impl.yml +++ b/.github/workflows/doc-build-impl.yml @@ -85,44 +85,43 @@ jobs: artifact-url: ${{ steps.upload.outputs.artifact-url }} steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.ref }} persist-credentials: false - name: Checkout support code - uses: actions/checkout@v7 - with: - repository: hpcflow/github-support - path: github-support - ref: ${{ inputs.script-branch }} - persist-credentials: false + uses: $/checkout-self - name: Init Python ${{ inputs.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ inputs.python-version }} - name: Install and configure poetry ${{ inputs.poetry-version }} - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry with: version: ${{ inputs.poetry-version }} - name: Cache Virtual Environment - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: sphinx version: ${{ inputs.python-version }} - name: Install Dependencies run: | - poetry install ${{ inputs.install-args }} + poetry install $Args + env: + Args: ${{ inputs.install-args }} - name: Configure Problem Matcher run: echo "::add-matcher::github-support/problem-matchers/sphinx.json" # See: https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md # See: https://github.com/python/cpython/pull/20325 - name: Run Sphinx run: | - poetry run make clean html ${{ inputs.sphinx-args }} + poetry run make clean html $Args + env: + Args: ${{ inputs.sphinx-args }} working-directory: docs - name: Upload documentation artifact id: upload - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.artifact-root-name }}-documentation (${{ inputs.ref }}) path: docs/build/html @@ -148,17 +147,17 @@ jobs: page-url: ${{ steps.deployment.outputs.page_url }} steps: - name: Download documentation artifact - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: site merge-multiple: true - name: Setup GitHub Pages - uses: actions/configure-pages@v6 + uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0 - name: Upload artifact to documentation staging - uses: actions/upload-pages-artifact@v5 + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: # Upload dist repository path: site - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v5 + uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 diff --git a/.github/workflows/release-impl.yml b/.github/workflows/release-impl.yml index 18d663b..0759018 100644 --- a/.github/workflows/release-impl.yml +++ b/.github/workflows/release-impl.yml @@ -170,16 +170,17 @@ jobs: changelog: ${{ steps.upload-changelog.outputs.artifact-url }} steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 # get all history and tags ref: ${{ inputs.pr-base-ref }} token: ${{ secrets.commit-token }} + persist-credentials: true allow-unsafe-pr-checkout: true - name: Configure git - uses: hpcflow/github-support/configure-git@0.5 + uses: $/configure-git - name: Set up python ${{ inputs.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ inputs.python-version }} @@ -215,19 +216,21 @@ jobs: - name: Commitizen bump # First update version number to latest stable release, then bump to new stable release, add a new tag and commit if: inputs.pr-base-ref == inputs.release_branch run: | - python3 -c " + python3 -c ' from commitizen.bump import update_version_in_files + import os update_version_in_files( - current_version='$pre_tag'.lstrip('v'), - new_version='$cur_tag'.lstrip('v'), - version_files=['pyproject.toml', '${{ inputs.version_file }}'], + current_version=os.environ["pre_tag"].lstrip("v"), + new_version=os.environ["cur_tag"].lstrip("v"), + version_files=["pyproject.toml", os.environ["ver_file"]], check_consistency=False, - encoding='utf-8', - )" + encoding="utf-8", + )' cz bump env: pre_tag: ${{ steps.pre_tag.outputs.tag }} cur_tag: ${{ steps.cur_tag.outputs.tag }} + ver_file: ${{ inputs.version_file }} - name: Get new tag id: new_tag @@ -260,22 +263,25 @@ jobs: - name: Rebase into develop branch if exists (stable release) if: inputs.pr-base-ref == inputs.release_branch run: | - exists_in_remote=$(git ls-remote --heads origin refs/heads/${{ inputs.pre_release_branch }}) + exists_in_remote=$(git ls-remote --heads origin "refs/heads/$PRE_BRANCH") echo "exists_in_remote: $exists_in_remote" if [[ -n $exists_in_remote ]]; then export SKIP=end-of-file-fixer - git checkout ${{ inputs.pre_release_branch }} + git checkout "$PRE_BRANCH" git pull - git rebase ${{ inputs.release_branch }} - git push -u origin ${{ inputs.pre_release_branch }} + git rebase "$BASE_BRANCH" + git push -u origin "$PRE_BRANCH" else - echo "No ${{ inputs.pre_release_branch }} branch to merge into." + echo "No $PRE_BRANCH branch to merge into." fi + env: + PRE_BRANCH: ${{ inputs.pre_release_branch }} + BASE_BRANCH: ${{ inputs.release_branch }} - name: Generate incremental CHANGELOG for GitHub release body (stable release) if: inputs.pr-base-ref == inputs.release_branch run: | - ./git-chglog --template .chglog/RELEASE.tpl.md --output CHANGELOG_increment.md $cur_tag.. + ./git-chglog --template .chglog/RELEASE.tpl.md --output CHANGELOG_increment.md "$cur_tag.."" cat CHANGELOG_increment.md env: cur_tag: ${{ steps.cur_tag.outputs.tag }} @@ -284,13 +290,13 @@ jobs: - name: Generate incremental CHANGELOG for GitHub release body (pre-release) if: inputs.pr-base-ref == inputs.pre_release_branch run: | - ./git-chglog --template .chglog/RELEASE.tpl.md --output CHANGELOG_increment.md $new_tag + ./git-chglog --template .chglog/RELEASE.tpl.md --output CHANGELOG_increment.md "$new_tag" cat CHANGELOG_increment.md env: new_tag: ${{ steps.new_tag.outputs.tag }} - name: Store the incremental CHANGELOG - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 id: upload-changelog with: name: CHANGELOG_increment @@ -305,24 +311,24 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.pr-base-ref }} allow-unsafe-pr-checkout: true persist-credentials: false - name: Set up python - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ inputs.python-version }} - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry with: version: ${{ inputs.poetry-version }} - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: test version: ${{ inputs.python-version }} @@ -333,11 +339,13 @@ jobs: - name: Cache all app data and programs run: | - poetry run ${{ inputs.executable_name }} manage cache-all + poetry run "$EXE_NAME" manage cache-all + env: + EXE_NAME: ${{ inputs.executable_name }} - name: Upload all cached app data/programs id: upload-cached-app-data - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.executable_name }}-app-data-cache path: ~/.cache/${{ inputs.executable_name }} @@ -365,29 +373,29 @@ jobs: BUILT_EXE_PATH_FILE: ${{ inputs.pyinstaller_dir }}/dist/onefile/${{ inputs.executable_name }}-${{ needs.bump-version.outputs.new_tag }}-${{ matrix.executable_os }}${{ matrix.executable_ext }} steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.pr-base-ref }} # otherwise we get the ref when the workflow started (missing above commit) allow-unsafe-pr-checkout: true persist-credentials: false - name: Set up python ${{ inputs.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ inputs.python-version }} - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: build version: ${{ inputs.python-version }} - name: Download prepared cached app data - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ inputs.executable_name }}-app-data-cache path: ${{ inputs.executable_name }}-app-data-cache - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry with: version: ${{ inputs.poetry-version }} @@ -397,11 +405,13 @@ jobs: - name: Install cached app data env: PYTHONUTF8: 1 + EXE_NAME: ${{ inputs.executable_name }} run: | - poetry run ${{ inputs.executable_name }} data install-cache ${{ inputs.executable_name }}-app-data-cache/data - poetry run ${{ inputs.executable_name }} data --list - poetry run ${{ inputs.executable_name }} program install-cache ${{ inputs.executable_name }}-app-data-cache/programs - poetry run ${{ inputs.executable_name }} program --list + poetry run "$EXE_NAME" data install-cache "${EXE_NAME}-app-data-cache/data" + poetry run "$EXE_NAME" data --list + poetry run "$EXE_NAME" program install-cache "${EXE_NAME}-app-data-cache/programs" + poetry run "$EXE_NAME" program --list + shell: bash - name: Build with pyinstaller (non-Windows, file) if: runner.os != 'Windows' @@ -432,27 +442,49 @@ jobs: TARGET: ${{ env.BUILT_EXE_BASE_NAME }}-${{ matrix.executable_os }}-dir - name: Version check (file) - uses: hpcflow/github-support/compare@0.5 + if: runner.os != 'Windows' + uses: $/compare + with: + expected: "${{ inputs.app_name }}, version ${{ needs.bump-version.outputs.version }}" + command: | + "$BUILT_EXE_PATH_FILE" --version + + - name: Version check (folder) + if: runner.os != 'Windows' + uses: $/compare + with: + expected: "${{ inputs.app_name }}, version ${{ needs.bump-version.outputs.version }}" + command: | + "$BUILT_EXE_PATH_DIR" --version + + - name: Version check (file) + if: runner.os == 'Windows' + uses: $/compare with: expected: "${{ inputs.app_name }}, version ${{ needs.bump-version.outputs.version }}" - command: ${{ env.BUILT_EXE_PATH_FILE }} --version + command: | + "$Env:BUILT_EXE_PATH_FILE" --version - name: Version check (folder) - uses: hpcflow/github-support/compare@0.5 + if: runner.os == 'Windows' + uses: $/compare with: expected: "${{ inputs.app_name }}, version ${{ needs.bump-version.outputs.version }}" - command: ${{ env.BUILT_EXE_PATH_DIR }} --version + command: | + "$Env:BUILT_EXE_PATH_DIR" --version - name: Run test suite on the frozen app (folder) env: GH_TOKEN: ${{ secrets.general-token }} run: | - ${{ env.BUILT_EXE_PATH_DIR }} test + "$BUILT_EXE_PATH_DIR" test - name: Compress folder (windows, folder) if: runner.os == 'Windows' working-directory: ${{ inputs.pyinstaller_dir }} - run: ./compress.ps1 -ExeName '${{ env.BUILT_EXE_BASE_NAME }}-${{ matrix.executable_os }}-dir' -BuildType 'onedir' + run: ./compress.ps1 -ExeName "$env:TARGET" -BuildType 'onedir' + env: + TARGET: ${{ env.BUILT_EXE_BASE_NAME }}-${{ matrix.executable_os }}-dir - name: Compress folder (non-windows, folder) if: runner.os != 'Windows' @@ -462,14 +494,14 @@ jobs: TARGET: ${{ env.BUILT_EXE_BASE_NAME }}-${{ matrix.executable_os }}-dir - name: Upload executable artifact (file) - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ env.BUILT_EXE_BASE_NAME }}-${{ matrix.executable_os }}${{ matrix.executable_ext }} path: ${{ env.BUILT_EXE_PATH_FILE }} retention-days: 7 - name: Upload executable artifact (compressed folder) - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ env.BUILT_EXE_BASE_NAME }}-${{ matrix.executable_os }}-dir.zip path: ${{ env.BUILT_EXE_PATH_DIR_ZIPPED }} @@ -485,85 +517,96 @@ jobs: BUILT_EXE_PATH_FILE: ${{ inputs.pyinstaller_dir }}/dist/onefile/${{ inputs.executable_name }}-${{ needs.bump-version.outputs.new_tag }}-linux steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.pr-base-ref }} # otherwise we get the ref when the workflow started (missing above commit) allow-unsafe-pr-checkout: true persist-credentials: false - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: build version: ${{ inputs.python-version }} - name: Download prepared cached app data - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ inputs.executable_name }}-app-data-cache path: ${{ inputs.executable_name }}-app-data-cache - name: Build executables within Docker - uses: addnab/docker-run-action@v3 + uses: $/run-in-docker with: - image: ghcr.io/hpcflow/rockylinux8-python:latest options: | -v ${{ github.workspace }}:/home - --env GH_TOKEN=${{ secrets.general-token }} + --env GH_TOKEN + --env BUILT_EXE_PATH_FILE + --env EXE_NAME + --env PYINST_DIR + --env BUILT_EXE_BASE_NAME + --env BUILT_EXE_PATH_DIR + --env EXPECTED run: | + vers_expected="$EXPECTED" + # set up poetry cd /home poetry config virtualenvs.in-project true poetry install --without dev - vers_expected="${{ inputs.app_name }}, version ${{ needs.bump-version.outputs.version }}" # build with pyinstaller for Rocky Linux (file) - cd ${{ inputs.pyinstaller_dir }} - ./make.sh ${{ env.BUILT_EXE_BASE_NAME }}-linux INFO onefile + cd "$PYINST_DIR" + ./make.sh "${BUILT_EXE_BASE_NAME}-linux" INFO onefile cd .. # version check (file) - vers=$(${{ env.BUILT_EXE_PATH_FILE }} --version) + vers=$("$BUILT_EXE_PATH_FILE" --version) echo $vers echo $vers_expected [ "$vers" = "$vers_expected" ] # install cache data - ${{ env.BUILT_EXE_PATH_FILE }} data install-cache ${{ inputs.executable_name }}-app-data-cache/data - ${{ env.BUILT_EXE_PATH_FILE }} data --list - ${{ env.BUILT_EXE_PATH_FILE }} program install-cache ${{ inputs.executable_name }}-app-data-cache/programs - ${{ env.BUILT_EXE_PATH_FILE }} program --list + "$BUILT_EXE_PATH_FILE" data install-cache "${EXE_NAME}-app-data-cache/data" + "$BUILT_EXE_PATH_FILE" data --list + "$BUILT_EXE_PATH_FILE" program install-cache "${EXE_NAME}-app-data-cache/programs" + "$BUILT_EXE_PATH_FILE" program --list # run test suite on the frozen app (file) - ${{ env.BUILT_EXE_PATH_FILE }} test + "$BUILT_EXE_PATH_FILE" test # build with pyinstaller for Rocky Linux (folder) - cd ${{ inputs.pyinstaller_dir }} - ./make.sh ${{ env.BUILT_EXE_BASE_NAME }}-linux-dir INFO onedir + cd "$PYINST_DIR" + ./make.sh "${BUILT_EXE_BASE_NAME}-linux-dir" INFO onedir cd .. # version check (folder) - vers=$(${{ env.BUILT_EXE_PATH_DIR }} --version) + vers=$("$BUILT_EXE_PATH_DIR" --version) echo $vers echo $vers_expected [ "$vers" = "$vers_expected" ] # run test suite on the frozen app (folder) - ${{ env.BUILT_EXE_PATH_DIR }} test + "$BUILT_EXE_PATH_DIR" test # Compress folder (folder) - cd ${{ inputs.pyinstaller_dir }} - ./compress.sh ${{ env.BUILT_EXE_BASE_NAME }}-linux-dir 'onedir' + cd "$PYINST_DIR" + ./compress.sh "${BUILT_EXE_BASE_NAME}-linux-dir" 'onedir' cd .. + env: + GH_TOKEN: ${{ secrets.general-token }} + EXE_NAME: ${{ inputs.executable_name }} + PYINST_DIR: ${{ inputs.pyinstaller_dir }} + EXPECTED: "${{ inputs.app_name }}, version ${{ needs.bump-version.outputs.version }}" - name: Upload executable artifact (file) - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ env.BUILT_EXE_BASE_NAME }}-linux path: ${{ env.BUILT_EXE_PATH_FILE }} retention-days: 7 - name: Upload executable artifact (compressed folder) - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ env.BUILT_EXE_BASE_NAME }}-linux-dir.zip path: ${{ inputs.pyinstaller_dir }}/dist/onedir/${{ env.BUILT_EXE_BASE_NAME }}-linux-dir.zip @@ -587,21 +630,21 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.ref }} allow-unsafe-pr-checkout: true persist-credentials: false - name: Set up python ${{ inputs.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python-version }} - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry with: version: ${{ inputs.poetry-version }} - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: benchmark version: ${{ matrix.python-version }} @@ -612,10 +655,16 @@ jobs: - name: Run app make workflow command run: | - poetry run ${{ inputs.executable_name }} --timeit-file benchmark_make_workflow_${{ matrix.num_elements }}_elements-${{ runner.os }}-py-${{ matrix.python-version }}.txt make ${{ inputs.benchmark_make_workflow }} --var N ${{ matrix.num_elements }} + poetry run "$EXE_NAME" --timeit-file "benchmark_make_workflow_${N_ELEM}_elements-${RUNNER_OS}-py-${PY_VER}.txt" make "$BENCHMARK" --var N "$N_ELEM" + env: + BENCHMARK: ${{ inputs.benchmark_make_workflow }} + EXE_NAME: ${{ inputs.executable_name }} + PY_VER: ${{ matrix.python-version }} + N_ELEM: ${{ matrix.num_elements }} + shell: bash - name: Store benchmark data - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: benchmark_make_workflow_${{ matrix.num_elements }}_elements-${{ runner.os }}-py-${{ matrix.python-version }}.txt path: benchmark_make_workflow_${{ matrix.num_elements }}_elements-${{ runner.os }}-py-${{ matrix.python-version }}.txt @@ -628,7 +677,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Delete cache artifact - uses: geekyeggo/delete-artifact@v6 + uses: geekyeggo/delete-artifact@176a747ab7e287e3ff4787bf8a148716375ca118 # v6.0.0 with: name: "*-app-data-cache" failOnError: false @@ -642,7 +691,7 @@ jobs: benchmark-url: ${{ steps.upload.outputs.artifact-url }} steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.ref }} allow-unsafe-pr-checkout: true @@ -651,7 +700,7 @@ jobs: run: | mkdir benchmarks - name: Load benchmark data - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: merge-multiple: true path: benchmarks @@ -659,7 +708,7 @@ jobs: run: | zip -r ./benchmarks.zip benchmarks - name: Store compound benchmark data - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: benchmarks.zip path: benchmarks.zip @@ -680,22 +729,22 @@ jobs: contents: write steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.pr-base-ref }} # otherwise we get the ref when the workflow started (missing above commit) allow-unsafe-pr-checkout: true persist-credentials: false - name: Set up python ${{ inputs.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ inputs.python-version }} - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: release version: ${{ inputs.python-version }} - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry with: version: ${{ inputs.poetry-version }} @@ -709,7 +758,7 @@ jobs: run: mkdir release-artifacts - name: Download release artifacts - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: release-artifacts @@ -718,7 +767,7 @@ jobs: - name: Release id: release - uses: softprops/action-gh-release@v3 + uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0 with: body_path: release-artifacts/CHANGELOG_increment/CHANGELOG_increment.md tag_name: ${{ needs.bump-version.outputs.new_tag }} @@ -734,78 +783,89 @@ jobs: - name: Release info id: get_binary_download_links + shell: python run: | - binaryYaml=$(python3 -c " - out_yaml = '' - exe_base = '${{ inputs.executable_name }}-${{ needs.bump-version.outputs.new_tag }}-' - url_base = 'https://github.com/${{ inputs.repository }}/releases/download/${{ needs.bump-version.outputs.new_tag }}/' - for i in ['win.exe', 'macOS', 'linux', 'win-dir.zip', 'macOS-dir.zip', 'linux-dir.zip']: - exe_name = f'{exe_base}{i}' - out_yaml += f'{exe_name}: {url_base}{exe_name}\n' - print(out_yaml) - ") - # Save multiline output - EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) - echo "binary_download_links<<$EOF" >> $GITHUB_OUTPUT - echo "$binaryYaml" >> $GITHUB_OUTPUT - echo "$EOF" >> $GITHUB_OUTPUT + import os + import string + import random + exe_base = os.environ['EXE_BASE'] + url_base = os.environ['URL_BASE'] + eof = ''.join(random.choices(string.ascii_uppercase + string.digits, k=24)) + eof = os.environ['EOF'] + with open(os.environ['GITHUB_OUTPUT'], 'a') as f: + f.write(f'binary_download_links<<{eof}\n') + for suffix in ['win.exe', 'macOS', 'linux', 'win-dir.zip', 'macOS-dir.zip', 'linux-dir.zip']: + f.write(f'{exe_base}{suffix}: {url_base}{exe_base}{suffix}\n') + f.write(f'{eof}\n') + env: + EXE_BASE: ${{ inputs.executable_name }}-${{ needs.bump-version.outputs.new_tag }}- + URL_BASE: https://github.com/${{ inputs.repository }}/releases/download/${{ needs.bump-version.outputs.new_tag }}/ - name: Publish (to ${{ inputs.pypi-url }}) id: publish run: | - poetry config repositories.pypi ${{ inputs.pypi-url }} - poetry config pypi-token.pypi ${{ secrets.pypi-token }} + poetry config repositories.pypi "$URL" + poetry config pypi-token.pypi "$TOKEN" poetry publish --repository pypi + env: + URL: ${{ inputs.pypi-url }} + TOKEN: ${{ secrets.pypi-token }} build-documentation: needs: release-github-PyPI runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 # get all history and tags ref: ${{ inputs.pr-base-ref }} # otherwise we get the ref when the workflow started (missing above commit) token: ${{ secrets.commit-token }} + persist-credentials: false allow-unsafe-pr-checkout: true - name: Configure git - uses: hpcflow/github-support/configure-git@0.5 + uses: $/configure-git - name: Set up python ${{ inputs.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ inputs.python-version }} - name: Write binary links YAML file and push run: | - echo -e "${{ needs.release-github-PyPI.outputs.binary_download_links }}" > docs/source/released_binaries.yml + echo -e "$BIN_LINKS" > docs/source/released_binaries.yml git add . git commit -m "build: update binary download links file [skip ci]" git push + env: + BIN_LINKS: ${{ needs.release-github-PyPI.outputs.binary_download_links }} - name: Rebase into develop branch if exists (stable release) if: inputs.pr-base-ref == inputs.release_branch run: | - exists_in_remote=$(git ls-remote --heads origin refs/heads/${{ inputs.pre_release_branch }}) + exists_in_remote=$(git ls-remote --heads origin "refs/heads/$PRE_BRANCH") echo "exists_in_remote: $exists_in_remote" if [[ -n $exists_in_remote ]]; then export SKIP=end-of-file-fixer - git checkout ${{ inputs.pre_release_branch }} + git checkout "$PRE_BRANCH" git pull - git rebase ${{ inputs.release_branch }} - git push -u origin ${{ inputs.pre_release_branch }} + git rebase "$BASE_BRANCH" + git push -u origin "$PRE_BRANCH" else - echo "No ${{ inputs.pre_release_branch }} branch to merge into." + echo "No $PRE_BRANCH branch to merge into." fi + env: + PRE_BRANCH: ${{ inputs.pre_release_branch }} + BASE_BRANCH: ${{ inputs.release_branch }} - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: release-doc version: ${{ inputs.python-version }} - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry with: version: ${{ inputs.poetry-version }} @@ -819,7 +879,7 @@ jobs: working-directory: docs - name: Upload documentation artifact - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: docs_html path: docs/build/html @@ -831,22 +891,23 @@ jobs: publish-state: ${{ steps.publish.outcome }} steps: - name: Set up python ${{ inputs.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ inputs.python-version }} - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: ${{ inputs.website_source_org }}/${{ inputs.website_source_repo }} token: ${{ secrets.website-token }} + persist-credentials: true allow-unsafe-pr-checkout: true - name: Configure git - uses: hpcflow/github-support/configure-git@0.5 + uses: $/configure-git - name: Download documentation artifact - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: docs_html path: docs/${{ needs.bump-version.outputs.new_tag }} @@ -854,21 +915,26 @@ jobs: - name: Update stable docs symlink if: inputs.pr-base-ref == inputs.release_branch run: | - ln -sfn ${{ needs.bump-version.outputs.new_tag }} docs/stable + ln -sfn "$TAG" docs/stable + env: + TAG: ${{ needs.bump-version.outputs.new_tag }} - name: Update pre-release docs symlink if: inputs.pr-base-ref == inputs.pre_release_branch run: | - ln -sfn ${{ needs.bump-version.outputs.new_tag }} docs/dev + ln -sfn "$TAG" docs/dev + env: + TAG: ${{ needs.bump-version.outputs.new_tag }} - run: tree - name: Update doc version switcher run: | - curl $URL --output docs/make_vers_switcher.py - python docs/make_vers_switcher.py ${{ inputs.docs_url_prefix }} + curl "$URL" --output docs/make_vers_switcher.py + python docs/make_vers_switcher.py "$DOC_PREFIX" env: URL: https://raw.githubusercontent.com/${{ inputs.repository }}/${{ github.ref_name }}/docs/make_vers_switcher.py + DOC_PREFIX: ${{ inputs.docs_url_prefix }} - name: Push changes id: publish diff --git a/.github/workflows/run-zizmor.yml b/.github/workflows/run-zizmor.yml new file mode 100644 index 0000000..343e03f --- /dev/null +++ b/.github/workflows/run-zizmor.yml @@ -0,0 +1,24 @@ +name: GitHub Actions Security Analysis with zizmor 🌈 + +on: + push: + branches: ["main"] + pull_request: + branches: ["**"] + +permissions: {} + +jobs: + zizmor: + name: Scan with Zizmor + runs-on: ubuntu-latest + permissions: + security-events: write + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Run zizmor 🌈 + uses: zizmorcore/zizmor-action@70fb788f84895a7701f5643d103d587e460b5c99 # v0.6.3 diff --git a/.github/workflows/test-impl.yml b/.github/workflows/test-impl.yml index f19771b..e221620 100644 --- a/.github/workflows/test-impl.yml +++ b/.github/workflows/test-impl.yml @@ -146,16 +146,17 @@ jobs: timeout-minutes: 2 steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: token: ${{ secrets.pre-commit-token }} # checkout PR source branch (head_ref) if event is pull_request: ref: ${{ inputs.head-ref || inputs.ref }} repository: ${{ inputs.full-repo-name }} + persist-credentials: true - name: Configure git for commits - uses: hpcflow/github-support/configure-git@0.5 + uses: $/configure-git - name: Set up python - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.13" @@ -184,24 +185,24 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.ref }} persist-credentials: false - name: Set up python - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.13" - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry timeout-minutes: ${{ inputs.install-poetry-timeout-minutes }} with: version: ${{ inputs.poetry-version }} - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: test version: "3.13" @@ -213,11 +214,13 @@ jobs: - name: Cache all app data and programs run: | - poetry run python -m ${{ inputs.CLI_module }} manage cache-all + poetry run python -m "$CLI_MODULE" manage cache-all + env: + CLI_MODULE: ${{ inputs.CLI_module }} - name: Upload all cached app data/programs id: upload-cached-app-data - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ inputs.executable_name }}-app-data-cache path: ~/.cache/${{ inputs.executable_name }} @@ -240,28 +243,28 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.ref }} persist-credentials: false - name: Set up python ${{ matrix.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python-version }} - name: Download prepared cached app data - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ inputs.executable_name }}-app-data-cache path: ${{ inputs.executable_name }}-app-data-cache - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry timeout-minutes: ${{ inputs.install-poetry-timeout-minutes }} with: version: ${{ inputs.poetry-version }} - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: test version: ${{ matrix.python-version }} @@ -272,21 +275,27 @@ jobs: poetry install --without dev,pyinstaller - name: Install cached app data + shell: bash env: PYTHONUTF8: 1 + EXE_NAME: ${{ inputs.executable_name }} run: | - poetry run ${{ inputs.executable_name }} data install-cache ${{ inputs.executable_name }}-app-data-cache/data - poetry run ${{ inputs.executable_name }} data --list - poetry run ${{ inputs.executable_name }} program install-cache ${{ inputs.executable_name }}-app-data-cache/programs - poetry run ${{ inputs.executable_name }} program --list + poetry run "$EXE_NAME" data install-cache "${EXE_NAME}-app-data-cache/data" + poetry run "$EXE_NAME" data --list + poetry run "$EXE_NAME" program install-cache "${EXE_NAME}-app-data-cache/programs" + poetry run "$EXE_NAME" program --list - name: Run tests + shell: bash timeout-minutes: ${{ inputs.unit-test-timeout-minutes }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} PYTHONUNBUFFERED: ok + EXE_NAME: ${{ inputs.executable_name }} + PYTEST_ARGS: ${{ inputs.pytest_args }} + UT_ARGS: ${{ inputs.unit_test_args }} run: | - poetry run ${{ inputs.executable_name }} test ${{ inputs.pytest_args }} ${{ inputs.unit_test_args }} + poetry run "$EXE_NAME" test $PYTEST_ARGS $UT_ARGS test-units-RockyLinux: needs: [pre-commit, cache-app-data] @@ -297,39 +306,44 @@ jobs: contents: read steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.ref }} persist-credentials: false - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: test version: RockyLinux - name: Download prepared cached app data - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ inputs.executable_name }}-app-data-cache path: ${{ inputs.executable_name }}-app-data-cache - name: Run unit tests within Docker - uses: addnab/docker-run-action@v3 + uses: $/run-in-docker with: - image: ghcr.io/hpcflow/rockylinux8-python:latest options: | -v ${{ github.workspace }}:/home - --env GH_TOKEN=${{ secrets.GITHUB_TOKEN }} + --env GH_TOKEN + --env EXE_NAME + --env UT_ARGS run: | cd /home poetry config virtualenvs.in-project true poetry install --without dev,pyinstaller - poetry run ${{ inputs.executable_name }} data install-cache ${{ inputs.executable_name }}-app-data-cache/data - poetry run ${{ inputs.executable_name }} program install-cache ${{ inputs.executable_name }}-app-data-cache/programs - poetry run ${{ inputs.executable_name }} data --list - poetry run ${{ inputs.executable_name }} program --list + poetry run "$EXE_NAME" data install-cache "${EXE_NAME}-app-data-cache/data" + poetry run "$EXE_NAME" program install-cache "${EXE_NAME}-app-data-cache/programs" + poetry run "$EXE_NAME" data --list + poetry run "$EXE_NAME" program --list export PYTHONUNBUFFERED=ok - poetry run ${{ inputs.executable_name }} test ${{ inputs.unit_test_args }} + poetry run "$EXE_NAME" test $UT_ARGS + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + EXE_NAME: ${{ inputs.executable_name }} + UT_ARGS: ${{ inputs.unit_test_args }} timeout-minutes: ${{ inputs.unit-test-timeout-minutes }} test-integration: @@ -349,27 +363,27 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.ref }} persist-credentials: false - name: Set up python ${{ matrix.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python-version }} - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry timeout-minutes: ${{ inputs.install-poetry-timeout-minutes }} with: version: ${{ inputs.poetry-version }} - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: test-integration version: ${{ matrix.python-version }} - name: Download prepared cached app data - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ inputs.executable_name }}-app-data-cache path: ${{ inputs.executable_name }}-app-data-cache @@ -380,21 +394,27 @@ jobs: poetry install --without dev,pyinstaller - name: Install cached app data + shell: bash env: PYTHONUTF8: 1 + EXE_NAME: ${{ inputs.executable_name }} run: | - poetry run ${{ inputs.executable_name }} data install-cache ${{ inputs.executable_name }}-app-data-cache/data - poetry run ${{ inputs.executable_name }} data --list - poetry run ${{ inputs.executable_name }} program install-cache ${{ inputs.executable_name }}-app-data-cache/programs - poetry run ${{ inputs.executable_name }} program --list + poetry run "$EXE_NAME" data install-cache "${EXE_NAME}-app-data-cache/data" + poetry run "$EXE_NAME" data --list + poetry run "$EXE_NAME" program install-cache "${EXE_NAME}-app-data-cache/programs" + poetry run "$EXE_NAME" program --list - name: Run integration tests + shell: bash timeout-minutes: ${{ inputs.integration-test-timeout-minutes }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} PYTHONUNBUFFERED: ok + EXE_NAME: ${{ inputs.executable_name }} + PYTEST_ARGS: ${{ inputs.pytest_args }} + IT_ARGS: ${{ inputs.integration_test_args }} run: | - poetry run ${{ inputs.executable_name }} test ${{ inputs.pytest_args }} --integration ${{ inputs.integration_test_args }} + poetry run "$EXE_NAME" test $PYTEST_ARGS --integration $IT_ARGS test-integration-RockyLinux: needs: [pre-commit, cache-app-data] @@ -405,39 +425,44 @@ jobs: contents: read steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.ref }} persist-credentials: false - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: test-integration version: RockyLinux - name: Download prepared cached app data - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ inputs.executable_name }}-app-data-cache path: ${{ inputs.executable_name }}-app-data-cache - name: Run integration tests within Docker - uses: addnab/docker-run-action@v3 + uses: $/run-in-docker with: - image: ghcr.io/hpcflow/rockylinux8-python:latest options: | -v ${{ github.workspace }}:/home - --env GH_TOKEN=${{ secrets.GITHUB_TOKEN }} + --env GH_TOKEN + --env EXE_NAME + --env IT_ARGS run: | cd /home poetry config virtualenvs.in-project true poetry install --without dev,pyinstaller - poetry run ${{ inputs.executable_name }} data install-cache ${{ inputs.executable_name }}-app-data-cache/data - poetry run ${{ inputs.executable_name }} program install-cache ${{ inputs.executable_name }}-app-data-cache/programs - poetry run ${{ inputs.executable_name }} data --list - poetry run ${{ inputs.executable_name }} program --list + poetry run "$EXE_NAME" data install-cache "${EXE_NAME}-app-data-cache/data" + poetry run "$EXE_NAME" program install-cache "${EXE_NAME}-app-data-cache/programs" + poetry run "$EXE_NAME" data --list + poetry run "$EXE_NAME" program --list export PYTHONUNBUFFERED=ok - poetry run ${{ inputs.executable_name }} test --integration ${{ inputs.integration_test_args }} + poetry run "$EXE_NAME" test --integration $IT_ARGS + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + EXE_NAME: ${{ inputs.executable_name }} + IT_ARGS: ${{ inputs.integration_test_args }} timeout-minutes: ${{ inputs.integration-test-timeout-minutes }} test-invocation-ubuntu: @@ -452,29 +477,24 @@ jobs: contents: read steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.ref }} persist-credentials: false - name: Checkout supporting test infrastructure - uses: actions/checkout@v7 - with: - repository: hpcflow/github-support - path: github-support - ref: ${{ inputs.script-branch }} - persist-credentials: false + uses: $/checkout-self - name: Set up python ${{ matrix.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python-version }} - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry id: poetry timeout-minutes: ${{ inputs.install-poetry-timeout-minutes }} with: version: ${{ inputs.poetry-version }} - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: test-invocation version: ${{ matrix.python-version }} @@ -495,57 +515,83 @@ jobs: PY: ${{ steps.poetry.outputs.python-path }} - name: Test invocation command with `python ./${{ inputs.CLI_path }}` - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: source ${{ steps.poetry.outputs.poetry-path }}/bin/activate - command: python ./${{ inputs.CLI_path }} internal get-invoc-cmd + init: source "$POETRY_PATH/bin/activate" + command: python "./${CLI_PATH}" internal get-invoc-cmd expected: "('${{ steps.poetry.outputs.python-path }}', '${{ github.workspace }}/${{ inputs.CLI_path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + CLI_PATH: ${{ inputs.CLI_path }} - name: Test invocation command with `python -m ${{ inputs.CLI_module }}` - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: source ${{ steps.poetry.outputs.poetry-path }}/bin/activate - command: python -m ${{ inputs.CLI_module }} internal get-invoc-cmd + init: source "$POETRY_PATH/bin/activate" + command: python -m "$CLI_MODULE" internal get-invoc-cmd expected: "('${{ steps.poetry.outputs.python-path }}', '${{ github.workspace }}/${{ inputs.CLI_path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + CLI_MODULE: ${{ inputs.CLI_module }} - name: Test invocation command with `${{ inputs.executable_name }}` entry point script - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: source ${{ steps.poetry.outputs.poetry-path }}/bin/activate - command: ${{ inputs.executable_name }} internal get-invoc-cmd + init: source "$POETRY_PATH/bin/activate" + command: | + "$EXE_NAME" internal get-invoc-cmd expected: "('${{ steps.poetry.outputs.python-path }}', '${{ steps.prep-test-data.outputs.exe-path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + EXE_NAME: ${{ inputs.executable_name }} - name: Test invocation command within a python script - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: source ${{ steps.poetry.outputs.poetry-path }}/bin/activate - command: python github-support/scripts/get_invoc_cmd.py ${{ inputs.app_package }} + init: source "$POETRY_PATH/bin/activate" + command: python github-support/scripts/get_invoc_cmd.py "$APP_PKG" expected: "('${{ steps.poetry.outputs.python-path }}', '${{ github.workspace }}/${{ inputs.CLI_path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + APP_PKG: ${{ inputs.app_package }} - name: Test invocation command with interactive python - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: source ${{ steps.poetry.outputs.poetry-path }}/bin/activate - command: python github-support/scripts/get_invoc_cmd_interactive.py python ${{ inputs.app_package }} + init: source "$POETRY_PATH/bin/activate" + command: python github-support/scripts/get_invoc_cmd_interactive.py python "$APP_PKG" expected: "('${{ steps.poetry.outputs.python-path }}', '${{ github.workspace }}/${{ inputs.CLI_path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + APP_PKG: ${{ inputs.app_package }} - name: Test invocation command with interactive ipython - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: source ${{ steps.poetry.outputs.poetry-path }}/bin/activate - command: python github-support/scripts/get_invoc_cmd_interactive.py ipython ${{ inputs.app_package }} + init: source "$POETRY_PATH/bin/activate" + command: python github-support/scripts/get_invoc_cmd_interactive.py ipython "$APP_PKG" expected: "('${{ steps.poetry.outputs.python-path }}', '${{ github.workspace }}/${{ inputs.CLI_path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + APP_PKG: ${{ inputs.app_package }} - name: Test direct workflow submission within a python script run: | - source ${{ steps.poetry.outputs.poetry-path }}/bin/activate - python github-support/scripts/test_direct_sub_python_script.py ${{ inputs.app_package }} + source "$POETRY_PATH/bin/activate" + python github-support/scripts/test_direct_sub_python_script.py "$APP_PKG" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + APP_PKG: ${{ inputs.app_package }} - name: Test direct workflow submission within a Jupyter notebook (via papermill) run: | - source ${{ steps.poetry.outputs.poetry-path }}/bin/activate + source "$POETRY_PATH/bin/activate" python -m ipykernel install --user --name python3 - papermill github-support/scripts/test_direct_sub_jupyter_notebook.ipynb papermill_out/test_direct_sub_jupyter_notebook_${{ matrix.python-version }}_${{ runner.os }}.ipynb -p app_import_str ${{ inputs.app_package }} + papermill github-support/scripts/test_direct_sub_jupyter_notebook.ipynb "papermill_out/test_direct_sub_jupyter_notebook_${PY_VER}_${RUNNER_OS}.ipynb" -p app_import_str "$APP_PKG" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + APP_PKG: ${{ inputs.app_package }} + PY_VER: ${{ matrix.python-version }} test-invocation-macos: if: inputs.invocation_tests == 'true' @@ -559,29 +605,24 @@ jobs: contents: read steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.ref }} persist-credentials: false - name: Checkout supporting test infrastructure - uses: actions/checkout@v7 - with: - repository: hpcflow/github-support - path: github-support - ref: ${{ inputs.script-branch }} - persist-credentials: false + uses: $/checkout-self - name: Set up python ${{ matrix.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python-version }} - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry id: poetry timeout-minutes: ${{ inputs.install-poetry-timeout-minutes }} with: version: ${{ inputs.poetry-version }} - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: test-invocation version: ${{ matrix.python-version }} @@ -602,57 +643,83 @@ jobs: PY: ${{ steps.poetry.outputs.python-path }} - name: Test invocation command with `python ./${{ inputs.CLI_path }}` - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: source ${{ steps.poetry.outputs.poetry-path }}/bin/activate - command: python ./${{ inputs.CLI_path }} internal get-invoc-cmd + init: source "$POETRY_PATH/bin/activate" + command: python "./${CLI_PATH}" internal get-invoc-cmd expected: "('${{ steps.poetry.outputs.python-path }}', '${{ github.workspace }}/${{ inputs.CLI_path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + CLI_PATH: ${{ inputs.CLI_path }} - name: Test invocation command with `python -m ${{ inputs.CLI_module }}` - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: source ${{ steps.poetry.outputs.poetry-path }}/bin/activate - command: python -m ${{ inputs.CLI_module }} internal get-invoc-cmd + init: source "$POETRY_PATH/bin/activate" + command: python -m "$CLI_MODULE" internal get-invoc-cmd expected: "('${{ steps.poetry.outputs.python-path }}', '${{ github.workspace }}/${{ inputs.CLI_path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + CLI_MODULE: ${{ inputs.CLI_module }} - name: Test invocation command with `${{ inputs.executable_name }}` entry point script - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: source ${{ steps.poetry.outputs.poetry-path }}/bin/activate - command: ${{ inputs.executable_name }} internal get-invoc-cmd + init: source "$POETRY_PATH/bin/activate" + command: | + "$EXE_NAME" internal get-invoc-cmd expected: "('${{ steps.poetry.outputs.python-path }}', '${{ steps.prep-test-data.outputs.exe-path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + EXE_NAME: ${{ inputs.executable_name }} - name: Test invocation command within a python script - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: source ${{ steps.poetry.outputs.poetry-path }}/bin/activate - command: python github-support/scripts/get_invoc_cmd.py ${{ inputs.app_package }} + init: source "$POETRY_PATH/bin/activate" + command: python github-support/scripts/get_invoc_cmd.py "$APP_PKG" expected: "('${{ steps.poetry.outputs.python-path }}', '${{ github.workspace }}/${{ inputs.CLI_path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + APP_PKG: ${{ inputs.app_package }} - name: Test invocation command with interactive python - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: source ${{ steps.poetry.outputs.poetry-path }}/bin/activate - command: python github-support/scripts/get_invoc_cmd_interactive.py python ${{ inputs.app_package }} + init: source "$POETRY_PATH/bin/activate" + command: python github-support/scripts/get_invoc_cmd_interactive.py python "$APP_PKG" expected: "('${{ steps.poetry.outputs.python-path }}', '${{ github.workspace }}/${{ inputs.CLI_path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + APP_PKG: ${{ inputs.app_package }} - name: Test invocation command with interactive ipython - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: source ${{ steps.poetry.outputs.poetry-path }}/bin/activate - command: python github-support/scripts/get_invoc_cmd_interactive.py ipython ${{ inputs.app_package }} + init: source "$POETRY_PATH/bin/activate" + command: python github-support/scripts/get_invoc_cmd_interactive.py ipython "$APP_PKG" expected: "('${{ steps.poetry.outputs.python-path }}', '${{ github.workspace }}/${{ inputs.CLI_path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + APP_PKG: ${{ inputs.app_package }} - name: Test direct workflow submission within a python script run: | - source ${{ steps.poetry.outputs.poetry-path }}/bin/activate - python github-support/scripts/test_direct_sub_python_script.py ${{ inputs.app_package }} + source "$POETRY_PATH/bin/activate" + python github-support/scripts/test_direct_sub_python_script.py "$APP_PKG" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + APP_PKG: ${{ inputs.app_package }} - name: Test direct workflow submission within a Jupyter notebook (via papermill) run: | - source ${{ steps.poetry.outputs.poetry-path }}/bin/activate + source "$POETRY_PATH/bin/activate" python -m ipykernel install --user --name python3 - papermill github-support/scripts/test_direct_sub_jupyter_notebook.ipynb papermill_out/test_direct_sub_jupyter_notebook_${{ matrix.python-version }}_${{ runner.os }}.ipynb -p app_import_str ${{ inputs.app_package }} + papermill github-support/scripts/test_direct_sub_jupyter_notebook.ipynb "papermill_out/test_direct_sub_jupyter_notebook_${PY_VER}_${RUNNER_OS}.ipynb" -p app_import_str "$APP_PKG" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + APP_PKG: ${{ inputs.app_package }} + PY_VER: ${{ matrix.python-version }} test-invocation-windows: if: inputs.invocation_tests == 'true' @@ -666,29 +733,24 @@ jobs: contents: read steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.ref }} persist-credentials: false - name: Checkout supporting test infrastructure - uses: actions/checkout@v7 - with: - repository: hpcflow/github-support - path: github-support - ref: ${{ inputs.script-branch }} - persist-credentials: false + uses: $/checkout-self - name: Set up python ${{ matrix.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python-version }} - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry id: poetry timeout-minutes: ${{ inputs.install-poetry-timeout-minutes }} with: version: ${{ inputs.poetry-version }} - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: test-invocation version: ${{ matrix.python-version }} @@ -711,43 +773,62 @@ jobs: PY: ${{ steps.poetry.outputs.python-path }} - name: Test invocation command with `python ./${{ inputs.CLI_path }}` - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: ."${{ steps.poetry.outputs.poetry-path }}\Scripts\activate.ps1" - command: python ./${{ inputs.CLI_path }} internal get-invoc-cmd + init: ."$Env:POETRY_PATH\Scripts\activate.ps1" + command: python ./$Env:CLI_PATH internal get-invoc-cmd expected: "('${{ steps.prep-test-data.outputs.python-path }}', '${{ steps.prep-test-data.outputs.cli-path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + CLI_PATH: ${{ inputs.CLI_path }} - name: Test invocation command with `python -m ${{ inputs.CLI_module }}` - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: ."${{ steps.poetry.outputs.poetry-path }}\Scripts\activate.ps1" - command: python -m ${{ inputs.CLI_module }} internal get-invoc-cmd + init: ."$Env:POETRY_PATH\Scripts\activate.ps1" + command: python -m $Env:CLI_MODULE internal get-invoc-cmd expected: "('${{ steps.prep-test-data.outputs.python-path }}', '${{ steps.prep-test-data.outputs.cli-path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + CLI_MODULE: ${{ inputs.CLI_module }} - name: Test invocation command with `${{ inputs.executable_name }}` entry point script - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: ."${{ steps.poetry.outputs.poetry-path }}\Scripts\activate.ps1" - command: ${{ inputs.executable_name }} internal get-invoc-cmd + init: ."$Env:POETRY_PATH\Scripts\activate.ps1" + command: $Env:EXE_NAME internal get-invoc-cmd expected: "('${{ steps.prep-test-data.outputs.python-path }}', '${{ steps.prep-test-data.outputs.exe-path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + EXE_NAME: ${{ inputs.executable_name }} - name: Test invocation command within a python script - uses: hpcflow/github-support/compare@0.5 + uses: $/compare with: - init: ."${{ steps.poetry.outputs.poetry-path }}\Scripts\activate.ps1" - command: python github-support\scripts\get_invoc_cmd.py ${{ inputs.app_package }} + init: ."$Env:POETRY_PATH\Scripts\activate.ps1" + command: python github-support\scripts\get_invoc_cmd.py $Env:APP_PKG expected: "('${{ steps.prep-test-data.outputs.python-path }}', '${{ steps.prep-test-data.outputs.cli-path }}')" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + APP_PKG: ${{ inputs.app_package }} - name: Test direct workflow submission within a python script run: | - ."${{ steps.poetry.outputs.poetry-path }}\Scripts\activate.ps1" - python github-support\scripts\test_direct_sub_python_script.py ${{ inputs.app_package }} + ."$Env:POETRY_PATH\Scripts\activate.ps1" + python github-support\scripts\test_direct_sub_python_script.py $Env:APP_PKG + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + APP_PKG: ${{ inputs.app_package }} - name: Test direct workflow submission within a Jupyter notebook (via papermill) run: | - ."${{ steps.poetry.outputs.poetry-path }}\Scripts\activate.ps1" + ."$Env:POETRY_PATH\Scripts\activate.ps1" python -m ipykernel install --user --name python3 - papermill github-support\scripts\test_direct_sub_jupyter_notebook.ipynb papermill_out\test_direct_sub_jupyter_notebook_${{ matrix.python-version }}_${{ runner.os }}.ipynb -p app_import_str ${{ inputs.app_package }} + papermill github-support\scripts\test_direct_sub_jupyter_notebook.ipynb "papermill_out\test_direct_sub_jupyter_notebook_$($Env:PY_VER)_$($Env:RUNNER_OS).ipynb" -p app_import_str "$Env:APP_PKG" + env: + POETRY_PATH: ${{ steps.poetry.outputs.poetry-path }} + APP_PKG: ${{ inputs.app_package }} + PY_VER: ${{ matrix.python-version }} cleanup-cache: needs: @@ -758,7 +839,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Delete cache artifact - uses: geekyeggo/delete-artifact@v6 + uses: geekyeggo/delete-artifact@176a747ab7e287e3ff4787bf8a148716375ca118 # v6.0.0 with: name: "*-app-data-cache" failOnError: false diff --git a/.github/workflows/test-pre-python-impl.yml b/.github/workflows/test-pre-python-impl.yml index df113ce..d9f68ec 100644 --- a/.github/workflows/test-pre-python-impl.yml +++ b/.github/workflows/test-pre-python-impl.yml @@ -46,22 +46,22 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.ref }} persist-credentials: false - name: Set up python ${{ matrix.python-version }} - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python-version }} allow-prereleases: true - name: Cache dependencies - uses: hpcflow/github-support/init-cache@0.5 + uses: $/init-cache with: name: test version: ${{ matrix.python-version }} - name: Set up poetry - uses: hpcflow/github-support/setup-poetry@0.5 + uses: $/setup-poetry with: version: ${{ inputs.poetry-version }} @@ -70,7 +70,9 @@ jobs: poetry install --without dev,pyinstaller - name: Run tests + shell: bash run: | - poetry run python -m pytest ${{ inputs.pytest-args }} + poetry run python -m pytest $ARGUMENTS env: PYTHONUNBUFFERED: ok + ARGUMENTS: ${{ inputs.pytest-args }} diff --git a/checkout-self/README.md b/checkout-self/README.md new file mode 100644 index 0000000..f24f033 --- /dev/null +++ b/checkout-self/README.md @@ -0,0 +1,2 @@ +# Check out this repository +Checks out this repository. Useful in some workflows, especially with self-references. diff --git a/checkout-self/action.yml b/checkout-self/action.yml new file mode 100644 index 0000000..36f86eb --- /dev/null +++ b/checkout-self/action.yml @@ -0,0 +1,20 @@ +name: Checkout this repository +description: > + Runs code in the context of a Rocky Linux 8 image. +inputs: + ref: + description: Reference to check out. + default: ${{ github.action_ref }} + path: + description: The path to check out as. + default: github-support +runs: + using: composite + steps: + - name: checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: hpcflow/github-support + path: ${{ inputs.path }} + ref: ${{ inputs.ref }} + persist-credentials: false diff --git a/compare/action.yml b/compare/action.yml index 67ab813..3d472de 100644 --- a/compare/action.yml +++ b/compare/action.yml @@ -20,7 +20,7 @@ runs: if: runner.os != 'Windows' run: | eval $INIT - actual=`$COMMAND` + actual=`eval $COMMAND` C='\033[0;33m' NC='\033[0m' echo -e "${C}actual:${NC} $actual" @@ -36,8 +36,8 @@ runs: if ($Env:INIT) { Invoke-Expression $Env:INIT } - $actual = (Invoke-Expression $Env:COMMAND) - $C = "$([char] 27)[0;33m" + $actual = (Invoke-Expression "& $Env:COMMAND") + $C = "$([char] 27)[0;33m" $NC = "$([char] 27)[0m" Write-Host "${C}actual:${NC} $actual" Write-Host "${C}expected:${NC} $Env:EXPECTED" diff --git a/init-cache/action.yml b/init-cache/action.yml index eca216a..88387fd 100644 --- a/init-cache/action.yml +++ b/init-cache/action.yml @@ -5,7 +5,7 @@ description: > inputs: name: description: The short name of the task having its environment cached. - required: true + required: true version: description: The version of Python this is for. required: true @@ -13,7 +13,7 @@ runs: using: composite steps: - name: Cache Virtual Environment - uses: actions/cache@v4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: ./.venv - key: ${{ inputs.name }}.${{ runner.os }}-${{ inputs.version }}-venv.${{ hashFiles('**/poetry.lock') }} + key: ${{ inputs.name }}.${{ runner.os }}-${{ inputs.version }}-venv.${{ github.head_ref || github.ref_name }}.${{ hashFiles('**/poetry.lock') }} diff --git a/run-in-docker/README.md b/run-in-docker/README.md new file mode 100644 index 0000000..5d1c441 --- /dev/null +++ b/run-in-docker/README.md @@ -0,0 +1,4 @@ +# Run code in Docker +A stripped down version of [addnab/docker-run-action](https://github.com/addnab/docker-run-action) that binds a particular image. + +Definitely not intended to be usable by anyone else. diff --git a/run-in-docker/action.yml b/run-in-docker/action.yml new file mode 100644 index 0000000..bf2cfbc --- /dev/null +++ b/run-in-docker/action.yml @@ -0,0 +1,18 @@ +name: Run code in Docker +description: > + Runs code in the context of a Rocky Linux 8 image. +inputs: + options: + description: Options to pass to docker + run: + description: The script to run in the container. + required: true +runs: + using: composite + steps: + - shell: bash + run: | + exec docker run $DockerOptions --entrypoint sh ghcr.io/hpcflow/rockylinux8-python:latest -c "$DockerRun" + env: + DockerOptions: ${{ inputs.options }} + DockerRun: ${{ inputs.run }} diff --git a/setup-poetry/action.yml b/setup-poetry/action.yml index 17657ab..27dbf70 100644 --- a/setup-poetry/action.yml +++ b/setup-poetry/action.yml @@ -24,7 +24,7 @@ runs: - name: Install shell: bash run: | - python -m pip install poetry==$VERSION + python -m pip install "poetry==$VERSION" env: VERSION: ${{ inputs.version }} - name: Configure