diff --git a/.github/actions/create-upload-suggestions/action.yml b/.github/actions/create-upload-suggestions/action.yml index b84e7885d00..1e66626a332 100644 --- a/.github/actions/create-upload-suggestions/action.yml +++ b/.github/actions/create-upload-suggestions/action.yml @@ -145,7 +145,9 @@ runs: - name: List all changed files tracked and untracked files shell: bash run: | - echo "Changed files: ${{ steps.git-changed-files.outputs.CHANGED_FILES }}" + echo "Changed files: ${CHANGED_FILES}" + env: + CHANGED_FILES: ${{ steps.git-changed-files.outputs.CHANGED_FILES }} - name: Add job summary without changed files shell: bash if: ${{ steps.files_changed.outputs.files_changed == 'false' }} diff --git a/.github/workflows/additional_checks.yml b/.github/workflows/additional_checks.yml index a2e895a78f7..4fbd15bdff8 100644 --- a/.github/workflows/additional_checks.yml +++ b/.github/workflows/additional_checks.yml @@ -23,6 +23,8 @@ jobs: additional-checks: name: Additional checks runs-on: ubuntu-24.04 + permissions: + contents: read steps: - name: Checkout repository contents @@ -37,6 +39,10 @@ jobs: python-version: "3.13" - name: Install uv and restore its cache uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 # v6.6.1 + with: + # To not have the last commit JSON and release notes files affected on + # releases, if copying the contents displayed in the CI logs. + enable-cache: false - name: Check that files with the same content are the same run: | @@ -56,11 +62,12 @@ jobs: # Using the last 30 commits (for branches, tags, and PRs). # End is the current (latest) commit. python ./utils/generate_release_notes.py log \ - ${{ github.ref_name }} \ - $(git rev-parse HEAD~30) \ + "${GITHUB_REF_NAME}" \ + "$(git rev-parse HEAD~30)" \ "" - name: "Cache pre-commit" - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 + # Not used for releases, only for running pre-commit + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 # zizmor: ignore[cache-poisoning] with: path: ~/.cache/pre-commit key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }} diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 86d8eac2833..a8f9fa0bf2e 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -26,7 +26,7 @@ jobs: build-cmake: runs-on: ubuntu-22.04 env: - CMakeVersion: "3.22.0" + CMAKE_VERSION: "3.22.0" steps: - name: Checkout GRASS uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 @@ -34,13 +34,13 @@ jobs: persist-credentials: false - name: Install CMake run: | - cd ${GITHUB_WORKSPACE} - arch=$(echo $(uname -s)-$(uname -m) | awk '{print tolower($0)}') - v=v${{ env.CMakeVersion }}/cmake-${{ env.CMakeVersion }}-${arch}.tar.gz - wget https://github.com/Kitware/CMake/releases/download/$v - tar xzf cmake-${{ env.CMakeVersion }}-${arch}.tar.gz - echo "CMAKE_DIR=$GITHUB_WORKSPACE/cmake-${{ env.CMakeVersion }}-${arch}/bin" >> $GITHUB_ENV - echo "$GITHUB_WORKSPACE/cmake-${{ env.CMakeVersion }}-${arch}/bin" >> $GITHUB_PATH + cd "${GITHUB_WORKSPACE}" || exit + arch="$(echo "$(uname -s)"-"$(uname -m)" | awk '{print tolower($0)}')" + v="v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-${arch}.tar.gz" + wget "https://github.com/Kitware/CMake/releases/download/$v" + tar xzf "cmake-${CMAKE_VERSION}-${arch}.tar.gz" + echo "CMAKE_DIR=${GITHUB_WORKSPACE}/cmake-${CMAKE_VERSION}-${arch}/bin" >> "${GITHUB_ENV}" + echo "${GITHUB_WORKSPACE}/cmake-${CMAKE_VERSION}-${arch}/bin" >> "${GITHUB_PATH}" - run: | cmake --version - name: Install dependencies @@ -58,25 +58,25 @@ jobs: ldd --version - name: Create installation directory run: | - mkdir $HOME/install + mkdir "${HOME}/install" - name: Configure run: | - cmake ${CMAKE_OPTIONS} -S $GITHUB_WORKSPACE -B $GITHUB_WORKSPACE/build -G Ninja \ - -DCMAKE_INSTALL_PREFIX=$HOME/install -DWITH_NLS=ON -DWITH_GUI=OFF -DWITH_DOCS=OFF \ + cmake -S "${GITHUB_WORKSPACE}" -B "${GITHUB_WORKSPACE}/build" -G Ninja \ + -DCMAKE_INSTALL_PREFIX="${HOME}/install" -DWITH_NLS=ON -DWITH_GUI=OFF -DWITH_DOCS=OFF \ -DWITH_READLINE=ON -DWITH_ODBC=ON -DWITH_NETCDF=ON -DWITH_BZLIB=ON - name: Print CMakeCache.txt shell: bash -el {0} run: | - cat ${GITHUB_WORKSPACE}/build/CMakeCache.txt + cat "${GITHUB_WORKSPACE}/build/CMakeCache.txt" - name: Build run: | - cmake --build build --verbose -j$(nproc) + cmake --build build --verbose -j"$(nproc)" - name: Install run: | - cmake --install $GITHUB_WORKSPACE/build --verbose + cmake --install "${GITHUB_WORKSPACE}/build" --verbose - name: Add the bin directory to PATH run: | - echo "$HOME/install/bin" >> $GITHUB_PATH + echo "${HOME}/install/bin" >> "${GITHUB_PATH}" - name: Print installed versions if: always() run: .github/workflows/print_versions.sh diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 8444cdad543..431be7ef7d0 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -70,11 +70,11 @@ jobs: - name: Set LD_LIBRARY_PATH for compilation run: | - echo "LD_LIBRARY_PATH=${HOME}/install/lib" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=${HOME}/install/lib" >> "${GITHUB_ENV}" - name: Set number of cores for compilation run: | - echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV + echo "MAKEFLAGS=-j$(nproc)" >> "${GITHUB_ENV}" - name: Build if: ${{ matrix.language == 'c-cpp' }} diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index fb288db5db4..81a8d32403b 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -30,7 +30,7 @@ jobs: - name: Create installation directory run: | - mkdir $HOME/install + mkdir "${HOME}/install" - name: Download Coverity Build Tool run: | @@ -43,11 +43,11 @@ jobs: - name: Set number of cores for compilation run: | - echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV + echo "MAKEFLAGS=-j$(nproc)" >> "${GITHUB_ENV}" - name: Set LD_LIBRARY_PATH for compilation run: | - echo "LD_LIBRARY_PATH=$HOME/install/lib" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=${HOME}/install/lib" >> "${GITHUB_ENV}" - name: Print build environment variables run: | @@ -57,11 +57,11 @@ jobs: - name: Configure run: | - echo "CFLAGS=${{ env.CFLAGS }}" >> $GITHUB_ENV - echo "CXXFLAGS=${{ env.CXXFLAGS }}" >> $GITHUB_ENV + echo "CFLAGS=${CFLAGS}" >> "${GITHUB_ENV}" + echo "CXXFLAGS=${CXXFLAGS}" >> "${GITHUB_ENV}" ./configure \ --enable-largefile \ - --prefix="$HOME/install/" \ + --prefix="${HOME}/install/" \ --with-blas \ --with-bzlib \ --with-cxx \ @@ -87,7 +87,8 @@ jobs: - name: Build with cov-build run: | pwd - export PATH="$(pwd)/cov-analysis-linux64/bin:${PATH}" + PATH="$(pwd)/cov-analysis-linux64/bin:${PATH}" + export PATH cov-build --dir cov-int make - name: Put results into Tarball diff --git a/.github/workflows/create_release_draft.yml b/.github/workflows/create_release_draft.yml index 214b37100c3..d0b1ac9e442 100644 --- a/.github/workflows/create_release_draft.yml +++ b/.github/workflows/create_release_draft.yml @@ -41,12 +41,12 @@ jobs: python-version: '3.13' - name: Create output directory run: | - mkdir ${{ env.OUT_DIR }} + mkdir "${OUT_DIR}" - name: Generate ChangeLog file run: | python utils/gitlog2changelog.py - mv ChangeLog ${{ env.OUT_DIR }}/ChangeLog - gzip ${{ env.OUT_DIR }}/ChangeLog + mv ChangeLog "${OUT_DIR}/ChangeLog" + gzip "${OUT_DIR}/ChangeLog" - name: Generate Git derived data files run: | echo "Generate VERSION_GIT file:" @@ -58,21 +58,21 @@ jobs: echo "Create core modules patch file:" git add core_modules_with_last_commit.json git diff --cached > \ - ${{ env.OUT_DIR }}/core_modules_with_last_commit.patch + "${OUT_DIR}/core_modules_with_last_commit.patch" - name: Create tarballs (for tags only) if: startsWith(github.ref, 'refs/tags/') run: | cd .. - tar -cvf ${{ env.OUT_DIR }}/${{ env.GRASS }}.tar \ + tar -cvf "${OUT_DIR}/${GRASS}.tar" \ --exclude=".gi*" --exclude=".tr*" \ - --transform s/grass/${{ env.GRASS }}/ grass - cd ${{ env.OUT_DIR }} - gzip -9k ${{ env.GRASS }}.tar - md5sum ${{ env.GRASS }}.tar.gz > ${{ env.GRASS }}.tar.gz.md5 - sha256sum ${{ env.GRASS }}.tar.gz > ${{ env.GRASS }}.tar.gz.sha256 - xz -9e ${{ env.GRASS }}.tar - md5sum ${{ env.GRASS }}.tar.xz > ${{ env.GRASS }}.tar.xz.md5 - sha256sum ${{ env.GRASS }}.tar.xz > ${{ env.GRASS }}.tar.xz.sha256 + --transform s/grass/"${GRASS}"/ grass + cd "${OUT_DIR}" || exit + gzip -9k "${GRASS}.tar" + md5sum "${GRASS}.tar.gz" > "${GRASS}.tar.gz.md5" + sha256sum "${GRASS}.tar.gz" > "${GRASS}.tar.gz.sha256" + xz -9e "${GRASS}.tar" + md5sum "${GRASS}.tar.xz" > "${GRASS}.tar.xz.md5" + sha256sum "${GRASS}.tar.xz" > "${GRASS}.tar.xz.sha256" - name: Publish draft distribution to GitHub (for tags only) if: startsWith(github.ref, 'refs/tags/') uses: softprops/action-gh-release@6cbd405e2c4e67a21c47fa9e383d020e4e28b836 # v2.3.3 diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index ff78915cd18..8db5f42b5ee 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -105,9 +105,9 @@ jobs: || github.ref == format('refs/heads/{0}', steps.tag-branch.outputs.latest_rel_branch) }}" echo "latest=${latest}" >> "${GITHUB_OUTPUT}" - echo "latest is $latest" + echo "latest is ${latest}" echo "current=${current}" >> "${GITHUB_OUTPUT}" - echo "current is $current" + echo "current is ${current}" - name: Docker meta id: meta uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0 @@ -160,7 +160,9 @@ jobs: && format('type=gha,scope={0}', matrix.os) || '' }} cache-to: type=gha,mode=max,scope=${{ matrix.os }} - name: Image digest - run: echo ${{ steps.docker_build.outputs.digest }} + run: echo "${STEPS_DOCKER_BUILD_OUTPUTS_DIGEST}" + env: + STEPS_DOCKER_BUILD_OUTPUTS_DIGEST: ${{ steps.docker_build.outputs.digest }} - name: Attest docker.io image uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0 # If there isn't a digest, an annotation cannot be added diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 4a331d7b64f..eea8ce0be2b 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -45,20 +45,29 @@ jobs: xargs -a <(awk '! /^ *(#|$)/' "grass/.github/workflows/apt.txt") -r -- \ sudo apt-get install -y --no-install-recommends --no-install-suggests - - name: Set up Python + - name: Set up Python (with cache) + if: ${{ contains(fromJSON('["push", "pull_request"]'), github.event_name) }} + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: ${{ env.PYTHON_VERSION }} + cache: pip # zizmor: ignore[cache-poisoning] Assuming push event is not used for tags + + - name: Set up Python (no cache, use for release artifacts) + if: ${{ !contains(fromJSON('["push", "pull_request"]'), github.event_name) }} uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 with: python-version: ${{ env.PYTHON_VERSION }} - cache: pip - name: Set version variables run: | - cd grass - eval $(./utils/update_version.py status --bash) - echo "MAJOR=$MAJOR" >> $GITHUB_ENV - echo "MINOR=$MINOR" >> $GITHUB_ENV - echo "VERSION=$VERSION" >> $GITHUB_ENV - echo "YEAR=$YEAR" >> $GITHUB_ENV + cd grass || exit + eval "$(./utils/update_version.py status --bash)" + { + echo "MAJOR=${MAJOR}" + echo "MINOR=${MINOR}" + echo "VERSION=${VERSION}" + echo "YEAR=${YEAR}" + } >> "${GITHUB_ENV}" - name: Checkout addons uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 @@ -69,13 +78,14 @@ jobs: fetch-depth: 0 persist-credentials: false - - name: ccache + - name: ccache (do not use for release artifacts) uses: hendrikmuhs/ccache-action@bfa03e1de4d7f7c3e80ad9109feedd05c4f5a716 # v1.2.19 + if: ${{ !contains(fromJSON('["push", "pull_request"]'), github.event_name) }} with: create-symlink: true verbose: 2 evict-old-files: 7d - key: ${{ github.workflow }}-${{ github.job }}-grass${{ env.MAJOR }}-${{ matrix.python-version }} + key: ${{ github.workflow }}-${{ github.job }}-grass${{ env.MAJOR }}-${{ env.PYTHON_VERSION }} - name: Install Python dependencies # We install both core and addon dependencies, but we don't install any @@ -86,6 +96,7 @@ jobs: pip install -r grass-addons/.github/workflows/requirements.txt - uses: rui314/setup-mold@725a8794d15fc7563f59595bd9556495c0564878 # v1 + if: ${{ !contains(fromJSON('["push", "pull_request"]'), github.event_name) }} - name: Create installation directory run: | @@ -170,11 +181,11 @@ jobs: - name: Compile addons run: | ./grass-addons/utils/cronjobs_osgeo_lxd/compile_addons_git.sh \ - "$MAJOR" \ - "$MINOR" \ - $(pwd)/grass-addons/src \ - $(grass --config path) \ - $(pwd)/addons-build-dir \ + "${MAJOR}" \ + "${MINOR}" \ + "$(pwd)/grass-addons/src" \ + "$(grass --config path)" \ + "$(pwd)/addons-build-dir" \ grass - name: Get target path for Markdown files @@ -183,24 +194,27 @@ jobs: - name: Move from build to target directory run: | - mkdir "$MKDOCS_DIR/source/addons" - mv -v addons-build-dir/docs/md/source/* "$MKDOCS_DIR/source/addons" + mkdir "${MKDOCS_DIR}/source/addons" + mv -v addons-build-dir/docs/md/source/* "${MKDOCS_DIR}/source/addons" - name: Build index run: | - export ARCH="$(grass --config arch)" - export ARCH_DISTDIR="$(grass --config path)" - export VERSION_NUMBER="$VERSION" + ARCH="$(grass --config arch)" + ARCH_DISTDIR="$(grass --config path)" + export ARCH + export ARCH_DISTDIR + export VERSION_NUMBER="${VERSION}" grass --tmp-project XY --exec \ - python grass/man/build_full_index.py md index "$MKDOCS_DIR/source/addons" addons + python grass/man/build_full_index.py md index "${MKDOCS_DIR}/source/addons" addons - name: Copy shared files to addons run: | - cd "$MKDOCS_DIR/source" + cd "${MKDOCS_DIR}/source" || exit # This should match directories with color tables and other files # linked from the pages. + # shellcheck disable=SC2010,SC2035 # TODO: Address these two issues for name in $(ls -1d */ | grep -vE "^(addons|libpython)/$"); do - cp -rv $name addons + cp -rv "${name}" addons done - name: Get mkdocs @@ -209,30 +223,30 @@ jobs: - name: Run mkdocs run: | - cd grass - eval $(./utils/update_version.py status --bash) + cd grass || exit + eval "$(./utils/update_version.py status --bash)" cd .. export SITE_NAME="GRASS $VERSION Documentation" export COPYRIGHT="© 2003-$YEAR GRASS Development Team, GRASS $VERSION Documentation" - cd $MKDOCS_DIR + cd "${MKDOCS_DIR}" || exit mkdocs build - name: Build Sphinx documentation run: | pip install -r "grass/python/grass/docs/requirements.txt" - cd grass + cd grass || exit make sphinxdoclib ARCH="$(grass --config arch)" - mv -v dist.$ARCH/docs/html/libpython $MKDOCS_DIR/site + mv -v dist."${ARCH}/docs/html/libpython" "${MKDOCS_DIR}/site" - name: Merge Sphinx and MkDocs Sitemaps run: | - cd grass + cd grass || exit python utils/merge_sitemaps.py \ - --mkdocs-sitemap "$MKDOCS_DIR/site/sitemap.xml" \ - --sphinx-sitemap "$MKDOCS_DIR/site/libpython/sitemap.xml" \ - --output "$MKDOCS_DIR/site/sitemap.xml" \ - --version $VERSION -o + --mkdocs-sitemap "${MKDOCS_DIR}/site/sitemap.xml" \ + --sphinx-sitemap "${MKDOCS_DIR}/site/libpython/sitemap.xml" \ + --output "${MKDOCS_DIR}/site/sitemap.xml" \ + --version "${VERSION}" -o - name: Make logs available uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 diff --git a/.github/workflows/gcc.yml b/.github/workflows/gcc.yml index 1db67a21ca8..78116f60264 100644 --- a/.github/workflows/gcc.yml +++ b/.github/workflows/gcc.yml @@ -40,13 +40,13 @@ jobs: sudo apt-get install -y --no-install-recommends --no-install-suggests - name: Create installation directory run: | - mkdir $HOME/install + mkdir "${HOME}/install" - name: Ensure one core for compilation run: | - echo "MAKEFLAGS=-j1" >> $GITHUB_ENV + echo "MAKEFLAGS=-j1" >> "${GITHUB_ENV}" - name: Set LD_LIBRARY_PATH for compilation run: | - echo "LD_LIBRARY_PATH=$HOME/install/lib" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=${HOME}/install/lib" >> "${GITHUB_ENV}" - name: Print build environment variables shell: bash -el {0} run: | @@ -60,5 +60,5 @@ jobs: # TODO: -pedantic-errors here won't compile CXXFLAGS: -std=${{ matrix.cpp }} -fPIC -Wall -Wextra run: | - .github/workflows/build_ubuntu-22.04.sh $HOME/install \ + .github/workflows/build_ubuntu-22.04.sh "${HOME}/install" \ -isystem/usr/include/gdal -Wpedantic -Werror diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml index 98bf97e90bd..cd45f826f28 100644 --- a/.github/workflows/label.yml +++ b/.github/workflows/label.yml @@ -9,7 +9,12 @@ name: Pull Request Labeler # https://github.com/actions/labeler/blob/master/README.md on: - - pull_request_target + # zizmor: ignore[dangerous-triggers] Labeler should be used with pull_request_target + pull_request_target: + # Limit pull_request_target execution to maintained branches + branches: + - main + - releasebranch_* permissions: {} diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 0016a428cbb..7baa9b5e73a 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -65,7 +65,7 @@ jobs: pyyaml run: | cp ./macos/files/conda-requirements-dev-arm64.txt "${RUNNER_TEMP}/macos_dependencies.txt" - echo "$test_dependencies" | sed "s/ /\n/g" >> "${RUNNER_TEMP}/macos_dependencies.txt" + echo "${test_dependencies// /\n}" >> "${RUNNER_TEMP}/macos_dependencies.txt" - name: Setup Mamba uses: mamba-org/setup-micromamba@7f29b8b80078b1b601dfa018b0f7425c587c63bb # v2.0.6 with: @@ -81,12 +81,12 @@ jobs: printenv | sort $CC --version - name: Create installation directory - run: mkdir $HOME/install + run: mkdir "${HOME}/install" - name: Build and install shell: micromamba-shell {0} - run: source ./.github/workflows/macos_install.sh $HOME/install + run: source ./.github/workflows/macos_install.sh "${HOME}/install" - name: Add the bin directory to PATH - run: echo "$HOME/install/bin" >> $GITHUB_PATH + run: echo "${HOME}/install/bin" >> "${GITHUB_PATH}" - name: Check installed version if: ${{ !cancelled() }} shell: micromamba-shell {0} @@ -95,8 +95,10 @@ jobs: - name: Run pytest with multiple workers in parallel shell: micromamba-shell {0} run: | - export PYTHONPATH=$(grass --config python_path):$PYTHONPATH - export LD_LIBRARY_PATH=$(grass --config path)/lib:$LD_LIBRARY_PATH + PYTHONPATH="$(grass --config python_path):${PYTHONPATH}" + LD_LIBRARY_PATH="$(grass --config path)/lib:${LD_LIBRARY_PATH}" + export PYTHONPATH + export LD_LIBRARY_PATH pytest \ @.github/workflows/pytest_args_ci.txt \ @.github/workflows/pytest_args_parallel.txt \ @@ -105,8 +107,10 @@ jobs: - name: Run pytest with a single worker (for tests marked with needs_solo_run) shell: micromamba-shell {0} run: | - export PYTHONPATH=$(grass --config python_path):$PYTHONPATH - export LD_LIBRARY_PATH=$(grass --config path)/lib:$LD_LIBRARY_PATH + PYTHONPATH="$(grass --config python_path):${PYTHONPATH}" + LD_LIBRARY_PATH="$(grass --config path)/lib:${LD_LIBRARY_PATH}" + export PYTHONPATH + export LD_LIBRARY_PATH pytest \ @.github/workflows/pytest_args_ci.txt \ @.github/workflows/pytest_args_not_parallel.txt \ @@ -115,8 +119,10 @@ jobs: - name: Run pytest with a single worker (for gunittest-based tests) shell: micromamba-shell {0} run: | - export PYTHONPATH=$(grass --config python_path):$PYTHONPATH - export LD_LIBRARY_PATH=$(grass --config path)/lib:$LD_LIBRARY_PATH + PYTHONPATH="$(grass --config python_path):${PYTHONPATH}" + LD_LIBRARY_PATH="$(grass --config path)/lib:${LD_LIBRARY_PATH}" + export PYTHONPATH + export LD_LIBRARY_PATH pytest \ @.github/workflows/pytest_args_gunittest.txt \ --junitxml=pytest.gunittest.junit.xml @@ -131,7 +137,7 @@ jobs: - name: Cache GRASS Sample Dataset id: cached-data - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 + uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 with: path: sample-data/nc_spm_full_v2alpha2.tar.gz key: nc_spm_full_v2alpha2.tar.gz @@ -146,6 +152,13 @@ jobs: SAMPLE_DATA: "https://grass.osgeo.org/sampledata/north_carolina/\ nc_spm_full_v2alpha2.tar.gz" + - name: Save GRASS Sample Dataset to cache + uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 + if: steps.cached-data.outputs.cache-hit != 'true' + with: + path: sample-data/nc_spm_full_v2alpha2.tar.gz + key: nc_spm_full_v2alpha2.tar.gz + - name: Run gunittest tests shell: micromamba-shell {0} run: .github/workflows/test_thorough.sh --config .github/workflows/macos_gunittest.cfg diff --git a/.github/workflows/macos_distribute_app.yml b/.github/workflows/macos_distribute_app.yml index 275ed61a572..c0adc7632ce 100644 --- a/.github/workflows/macos_distribute_app.yml +++ b/.github/workflows/macos_distribute_app.yml @@ -111,19 +111,22 @@ jobs: - name: Create config file shell: bash -el {0} env: - Config: ${HOME}/.config/grass/configure-build-${{ matrix.name }}.sh + CONFIG: ${HOME}/.config/grass/configure-build-${{ matrix.name }}.sh MACOS_CERTIFICATE_NAME: ${{ secrets.MACOS_CERTIFICATE_NAME }} + MATRIX_DEPLOYMENT_TARGET: ${{ matrix.deployment_target }} run: | mkdir -p "${HOME}/.config/grass" - echo sdk=\"$(xcrun --show-sdk-path)\" >> ${{ env.Config }} - echo deployment_target=\"${{ matrix.deployment_target }}\" >> ${{ env.Config }} - echo cs_ident=\"${MACOS_CERTIFICATE_NAME}\" >> ${{ env.Config }} - echo cs_keychain_profile=\"${KEYCHAIN_PROFILE}\" >> ${{ env.Config }} - echo cs_provisionprofile=\"${RUNNER_TEMP}/embedded.provisionprofile\" >> ${{ env.Config }} + { + echo sdk=\""$(xcrun --show-sdk-path)"\" + echo deployment_target=\""${MATRIX_DEPLOYMENT_TARGET}"\" + echo cs_ident=\""${MACOS_CERTIFICATE_NAME}"\" + echo cs_keychain_profile=\""${KEYCHAIN_PROFILE}"\" + echo cs_provisionprofile=\""${RUNNER_TEMP}/embedded.provisionprofile"\" + } >> "${CONFIG}" - name: Build GRASS app run: | - ./macos/build_grass_app.bash --with-liblas --notarize -o "${{ runner.temp }}" + ./macos/build_grass_app.bash --with-liblas --notarize -o "${RUNNER_TEMP}" - name: Upload DMG file as artifact if: ${{ success() && !cancelled() }} diff --git a/.github/workflows/milestones.yml b/.github/workflows/milestones.yml index 4e9fa634a75..41831313c2b 100644 --- a/.github/workflows/milestones.yml +++ b/.github/workflows/milestones.yml @@ -2,7 +2,7 @@ name: Assign Milestone on: - pull_request_target: + pull_request_target: # zizmor: ignore[dangerous-triggers] types: [closed] permissions: {} @@ -22,13 +22,16 @@ jobs: - name: Get current milestone title id: current-milestone run: | - echo "milestone<> "${GITHUB_OUTPUT}" - gh pr view ${{ github.event.pull_request.html_url }} --json milestone \ - --jq .milestone.title >> "${GITHUB_OUTPUT}" - echo 'EOF' >> "${GITHUB_OUTPUT}" + { + echo "milestone<> "${GITHUB_OUTPUT}" env: GH_TOKEN: ${{ github.token }} GH_REPO: ${{ github.repository }} + GITHUB_EVENT_PULL_REQUEST_HTML_URL: ${{ github.event.pull_request.html_url }} - name: PR already has a milestone run: echo "PR already has a milestone" if: ${{ steps.current-milestone.outputs.milestone }} @@ -39,12 +42,14 @@ jobs: if: ${{ !steps.current-milestone.outputs.milestone }} id: version-file run: | - echo "version<> "${GITHUB_OUTPUT}" - gh api \ - -H "Accept: application/vnd.github.raw" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - "/repos/{owner}/{repo}/contents/include/VERSION?ref=${{ github.sha }}" >> "${GITHUB_OUTPUT}" - echo "EOF" >> "${GITHUB_OUTPUT}" + { + echo "version<> "${GITHUB_OUTPUT}" env: GH_TOKEN: ${{ github.token }} GH_REPO: ${{ github.repository }} @@ -57,8 +62,8 @@ jobs: if: ${{ !steps.current-milestone.outputs.milestone }} id: milestone run: | - version=$(echo "$VERSIONFILE" | head -n 3 | xargs | sed 's/ /./g; s/\(RC[0-9]*\|dev\)//g') - echo "title=$version" >> "${GITHUB_OUTPUT}" + version=$(echo "${VERSIONFILE}" | head -n 3 | xargs | sed 's/ /./g; s/\(RC[0-9]*\|dev\)//g') + echo "title=${version}" >> "${GITHUB_OUTPUT}" env: VERSIONFILE: ${{ steps.version-file.outputs.version }} - name: Show milestone title @@ -68,8 +73,9 @@ jobs: MILESTONE: ${{ steps.milestone.outputs.title }} - name: Set PR milestone if: ${{ !steps.current-milestone.outputs.milestone }} - run: gh pr edit ${{ github.event.pull_request.html_url }} --milestone "${MILESTONE}" + run: gh pr edit "${GITHUB_EVENT_PULL_REQUEST_HTML_URL}" --milestone "${MILESTONE}" env: GH_TOKEN: ${{ github.token }} GH_REPO: ${{ github.repository }} MILESTONE: ${{ steps.milestone.outputs.title }} + GITHUB_EVENT_PULL_REQUEST_HTML_URL: ${{ github.event.pull_request.html_url }} diff --git a/.github/workflows/osgeo4w.yml b/.github/workflows/osgeo4w.yml index 1b40bcadf66..55d7f2af311 100644 --- a/.github/workflows/osgeo4w.yml +++ b/.github/workflows/osgeo4w.yml @@ -99,7 +99,7 @@ jobs: - name: Set number of cores for compilation run: | - echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV + echo "MAKEFLAGS=-j$(nproc)" >> "${GITHUB_ENV}" shell: msys2 {0} - name: Compile GRASS @@ -115,7 +115,7 @@ jobs: run: .github/workflows/print_versions.sh - name: Test executing of the grass command - run: .github/workflows/test_simple.bat '${{env.O4WROOT}}\opt\grass\grass85.bat' + run: .github/workflows/test_simple.bat '%O4WROOT%\opt\grass\grass85.bat' env: O4WROOT: ${{ steps.osgeo4w.outputs.root }} @@ -160,7 +160,7 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} - name: Run tests - run: .github/workflows/test_thorough.bat '${{env.O4WROOT}}\opt\grass\grass85.bat' '${{env.O4WROOT}}\bin\python3' + run: .github/workflows/test_thorough.bat '%O4WROOT%\opt\grass\grass85.bat' '%O4WROOT%\bin\python3' env: O4WROOT: ${{ steps.osgeo4w.outputs.root }} diff --git a/.github/workflows/periodic_update.yml b/.github/workflows/periodic_update.yml index 59cc17b0079..5f0e4f6f125 100644 --- a/.github/workflows/periodic_update.yml +++ b/.github/workflows/periodic_update.yml @@ -31,7 +31,7 @@ jobs: steps: - name: Create URL to the run output id: vars - run: echo "run-url=https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" >> $GITHUB_OUTPUT + run: echo "run-url=https://github.com/$GITHUB_REPOSITORY/actions/runs/${GITHUB_RUN_ID}" >> "${GITHUB_OUTPUT}" - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false @@ -60,8 +60,11 @@ jobs: - name: Check outputs if: ${{ steps.cpr.outputs.pull-request-number }} run: | - echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" - echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" + echo "Pull Request Number - ${STEPS_CPR_OUTPUTS_PULL_REQUEST_NUMBER}" + echo "Pull Request URL - ${STEPS_CPR_OUTPUTS_PULL_REQUEST_URL}" + env: + STEPS_CPR_OUTPUTS_PULL_REQUEST_NUMBER: ${{ steps.cpr.outputs.pull-request-number }} + STEPS_CPR_OUTPUTS_PULL_REQUEST_URL: ${{ steps.cpr.outputs.pull-request-url }} update-i18n: # The type of runner that the job will run on runs-on: ubuntu-latest @@ -74,7 +77,7 @@ jobs: steps: - name: Create URL to the run output id: vars - run: echo "run-url=https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" >> $GITHUB_OUTPUT + run: echo "run-url=https://github.com/$GITHUB_REPOSITORY/actions/runs/${GITHUB_RUN_ID}" >> "${GITHUB_OUTPUT}" - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false @@ -95,7 +98,7 @@ jobs: --without-opengl \ --without-pdal - name: Build grass core - run: make -j$(nproc) + run: make -j"$(nproc)" - name: Create .pot files (containing original messages) run: cd locale && make pot - name: Merge new messages (Done by Weblate plugin) @@ -133,12 +136,16 @@ jobs: branch: periodic/update-i18n title: "locale: Update translation files" body: | - This updates the .pot template files, as well as all language-specific .po files. + This updates the .pot template files, as well as all language-specific .po files + if the option was selected. [Workflow run summary](${{ steps.vars.outputs.run-url }}) Automated changes by [create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub action - name: Check outputs if: ${{ steps.changed-files.outcome == 'failure' && steps.cpr.outputs.pull-request-number }} run: | - echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" - echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" + echo "Pull Request Number - ${STEPS_CPR_OUTPUTS_PULL_REQUEST_NUMBER}" + echo "Pull Request URL - ${STEPS_CPR_OUTPUTS_PULL_REQUEST_URL}" + env: + STEPS_CPR_OUTPUTS_PULL_REQUEST_NUMBER: ${{ steps.cpr.outputs.pull-request-number }} + STEPS_CPR_OUTPUTS_PULL_REQUEST_URL: ${{ steps.cpr.outputs.pull-request-url }} diff --git a/.github/workflows/post-pr-reviews.yml b/.github/workflows/post-pr-reviews.yml index b952a1812ca..20b9c244d6b 100644 --- a/.github/workflows/post-pr-reviews.yml +++ b/.github/workflows/post-pr-reviews.yml @@ -2,6 +2,7 @@ name: Post PR code suggestions on: + # zizmor: ignore[dangerous-triggers] Only selected workflows, and whitelisted input values are used workflow_run: workflows: ["ClangFormat Check", "Python Code Quality"] types: diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index cf564aca902..c065a2c14a2 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -42,7 +42,7 @@ jobs: uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 with: python-version: ${{ matrix.python-version }} - cache: pip + cache: pip # zizmor: ignore[cache-poisoning] This pytest workflow not used for release artifacts allow-prereleases: true - name: Install non-Python dependencies @@ -63,18 +63,21 @@ jobs: - name: Create installation directory run: | - mkdir $HOME/install + mkdir "${HOME}/install" - name: Set number of cores for compilation run: | - echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV + echo "MAKEFLAGS=-j$(nproc)" >> "${GITHUB_ENV}" - name: Build - run: .github/workflows/build_${{ matrix.os }}.sh $HOME/install + run: | + ".github/workflows/build_${MATRIX_OS}.sh" "${HOME}/install" + env: + MATRIX_OS: ${{ matrix.os }} - name: Add the bin directory to PATH run: | - echo "$HOME/install/bin" >> $GITHUB_PATH + echo "${HOME}/install/bin" >> "${GITHUB_PATH}" - name: Print installed versions if: always() @@ -85,10 +88,14 @@ jobs: - name: Run pytest with multiple workers in parallel run: | - export PYTHONPATH=`grass --config python_path`:$PYTHONPATH - export LD_LIBRARY_PATH=$(grass --config path)/lib:$LD_LIBRARY_PATH - export INITIAL_GISBASE="$(grass --config path)" - export INITIAL_PWD="${PWD}" + PYTHONPATH="$(grass --config python_path):${PYTHONPATH}" + LD_LIBRARY_PATH="$(grass --config path)/lib:${LD_LIBRARY_PATH}" + INITIAL_GISBASE="$(grass --config path)" + INITIAL_PWD="${PWD}" + export PYTHONPATH + export LD_LIBRARY_PATH + export INITIAL_GISBASE + export INITIAL_PWD pytest \ @.github/workflows/pytest_args_ci.txt \ @.github/workflows/pytest_args_cov.txt \ @@ -98,10 +105,14 @@ jobs: - name: Run pytest with a single worker (for tests marked with needs_solo_run) run: | - export PYTHONPATH=`grass --config python_path`:$PYTHONPATH - export LD_LIBRARY_PATH=$(grass --config path)/lib:$LD_LIBRARY_PATH - export INITIAL_GISBASE="$(grass --config path)" - export INITIAL_PWD="${PWD}" + PYTHONPATH="$(grass --config python_path):${PYTHONPATH}" + LD_LIBRARY_PATH="$(grass --config path)/lib:${LD_LIBRARY_PATH}" + INITIAL_GISBASE="$(grass --config path)" + INITIAL_PWD="${PWD}" + export PYTHONPATH + export LD_LIBRARY_PATH + export INITIAL_GISBASE + export INITIAL_PWD pytest \ @.github/workflows/pytest_args_ci.txt \ @.github/workflows/pytest_args_cov.txt \ @@ -110,20 +121,28 @@ jobs: -k 'not testsuite' - name: Run pytest with a single worker (for gunittest-based tests) run: | - export PYTHONPATH=`grass --config python_path`:$PYTHONPATH - export LD_LIBRARY_PATH=$(grass --config path)/lib:$LD_LIBRARY_PATH - export INITIAL_GISBASE="$(grass --config path)" - export INITIAL_PWD="${PWD}" + PYTHONPATH="$(grass --config python_path):${PYTHONPATH}" + LD_LIBRARY_PATH="$(grass --config path)/lib:${LD_LIBRARY_PATH}" + INITIAL_GISBASE="$(grass --config path)" + INITIAL_PWD="${PWD}" + export PYTHONPATH + export LD_LIBRARY_PATH + export INITIAL_GISBASE + export INITIAL_PWD pytest \ @.github/workflows/pytest_args_cov.txt \ @.github/workflows/pytest_args_gunittest.txt \ --junitxml=pytest.gunittest.junit.xml - name: Fix non-standard installed script paths in coverage data run: | - export PYTHONPATH=`grass --config python_path`:$PYTHONPATH - export LD_LIBRARY_PATH=$(grass --config path)/lib:$LD_LIBRARY_PATH - export INITIAL_GISBASE="$(grass --config path)" - export INITIAL_PWD="${PWD}" + PYTHONPATH="$(grass --config python_path):${PYTHONPATH}" + LD_LIBRARY_PATH="$(grass --config path)/lib:${LD_LIBRARY_PATH}" + INITIAL_GISBASE="$(grass --config path)" + INITIAL_PWD="${PWD}" + export PYTHONPATH + export LD_LIBRARY_PATH + export INITIAL_GISBASE + export INITIAL_PWD python utils/coverage_mapper.py coverage combine coverage html diff --git a/.github/workflows/python-code-quality.yml b/.github/workflows/python-code-quality.yml index dd4f4de22a6..b0252699efb 100644 --- a/.github/workflows/python-code-quality.yml +++ b/.github/workflows/python-code-quality.yml @@ -45,13 +45,15 @@ jobs: steps: - name: Versions run: | - echo OS: ${{ matrix.os }} - echo Python: ${{ env.PYTHON_VERSION }} - echo Minimal Python version: ${{ env.MIN_PYTHON_VERSION }} - echo Flake8: ${{ env.FLAKE8_VERSION }} - echo Pylint: ${{ env.PYLINT_VERSION }} - echo Bandit: ${{ env.BANDIT_VERSION }} - echo Ruff: ${{ env.RUFF_VERSION }} + echo "OS: ${MATRIX_OS}" + echo "Python: ${PYTHON_VERSION}" + echo "Minimal Python version: ${MIN_PYTHON_VERSION}" + echo "Flake8: ${FLAKE8_VERSION}" + echo "Pylint: ${PYLINT_VERSION}" + echo "Bandit: ${BANDIT_VERSION}" + echo "Ruff: ${RUFF_VERSION}" + env: + MATRIX_OS: ${{ matrix.os }} - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: @@ -61,12 +63,12 @@ jobs: uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 with: python-version: ${{ env.PYTHON_VERSION }} - cache: pip + cache: pip # zizmor: ignore[cache-poisoning] Not creating release artifacts, less of a concern here - name: Upgrade pip run: python -m pip install --upgrade pip - name: Install Ruff - run: pip install ruff==${{ env.RUFF_VERSION }} + run: pip install "ruff==${RUFF_VERSION}" - name: Run Ruff (output annotations on fixable errors) run: ruff check --output-format=github . --preview --unsafe-fixes continue-on-error: true @@ -104,19 +106,19 @@ jobs: pip install -r .github/workflows/optional_requirements.txt pip install --user pipx pipx ensurepath - pipx install flake8==${{ env.FLAKE8_VERSION }} - pipx install pylint==${{ env.PYLINT_VERSION }} + pipx install "flake8==${FLAKE8_VERSION}" + pipx install "pylint==${PYLINT_VERSION}" pipx inject pylint -r .github/workflows/python_requirements.txt -r .github/workflows/optional_requirements.txt # The extra toml is only needed before Python 3.11 - pipx install bandit[sarif,toml]==${{ env.BANDIT_VERSION }} + pipx install "bandit[sarif,toml]==${BANDIT_VERSION}" - name: Run Flake8 run: | - flake8 --count --statistics --show-source --jobs=$(nproc) . + flake8 --count --statistics --show-source --jobs="$(nproc)" . - name: Run Flake8 on additional files run: | - flake8 --count --statistics --show-source --jobs=$(nproc) python/grass/{script,jupyter}/testsuite/ + flake8 --count --statistics --show-source --jobs="$(nproc)" python/grass/{script,jupyter}/testsuite/ - name: Bandit Vulnerability Scan run: | @@ -135,27 +137,32 @@ jobs: - name: Create installation directory run: | - mkdir $HOME/install + mkdir "${HOME}/install" - name: Set number of cores for compilation run: | - echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV + echo "MAKEFLAGS=-j$(nproc)" >> "${GITHUB_ENV}" - uses: rui314/setup-mold@725a8794d15fc7563f59595bd9556495c0564878 # v1 - name: Build - run: .github/workflows/build_${{ matrix.os }}.sh $HOME/install + run: | + ".github/workflows/build_${MATRIX_OS}.sh" "${HOME}/install" + env: + MATRIX_OS: ${{ matrix.os }} - name: Add the bin directory to PATH run: | - echo "$HOME/install/bin" >> $GITHUB_PATH + echo "${HOME}/install/bin" >> "${GITHUB_PATH}" - name: Run Pylint on grass package # Until slower checks (like similarity) are reenabled, running in one step is faster if: false run: | - export PYTHONPATH=`grass --config python_path`:$PYTHONPATH - export LD_LIBRARY_PATH=$(grass --config path)/lib:$LD_LIBRARY_PATH - pylint --persistent=no --py-version=${{ env.MIN_PYTHON_VERSION }} --jobs=$(nproc) grass + PYTHONPATH="$(grass --config python_path):$PYTHONPATH" + LD_LIBRARY_PATH="$(grass --config path)/lib:$LD_LIBRARY_PATH" + export PYTHONPATH + export LD_LIBRARY_PATH + pylint --persistent=no --py-version=${{ env.MIN_PYTHON_VERSION }} --jobs="$(nproc)" grass - name: Run Pylint on other files using pytest # Until slower checks (like similarity) are reenabled, running in one step is faster @@ -163,9 +170,11 @@ jobs: run: | pipx inject --include-apps pylint pytest pipx inject pylint pytest-pylint pytest-github-actions-annotate-failures pytest-timeout - export PYTHONPATH=`grass --config python_path`:$PYTHONPATH - export LD_LIBRARY_PATH=$(grass --config path)/lib:$LD_LIBRARY_PATH - pytest --pylint -m pylint --pylint-jobs=$(nproc) \ + PYTHONPATH="$(grass --config python_path):$PYTHONPATH" + LD_LIBRARY_PATH="$(grass --config path)/lib:$LD_LIBRARY_PATH" + export PYTHONPATH + export LD_LIBRARY_PATH + pytest --pylint -m pylint --pylint-jobs="$(nproc)" \ --pylint-ignore-patterns="${{ env.PylintIgnore }}" env: PylintIgnore: "python/.*,gui/.*" @@ -174,15 +183,19 @@ jobs: # Until slower checks (like similarity) are reenabled, running in one step is faster if: false run: | - export PYTHONPATH=`grass --config python_path`:$PYTHONPATH - export LD_LIBRARY_PATH=$(grass --config path)/lib:$LD_LIBRARY_PATH - pylint --persistent=no --py-version=${{ env.MIN_PYTHON_VERSION }} --jobs=$(nproc) gui + PYTHONPATH="$(grass --config python_path):$PYTHONPATH" + LD_LIBRARY_PATH="$(grass --config path)/lib:$LD_LIBRARY_PATH" + export PYTHONPATH + export LD_LIBRARY_PATH + pylint --persistent=no --py-version="${MIN_PYTHON_VERSION}" --jobs="$(nproc)" gui - name: Run Pylint all in one pass run: | - export PYTHONPATH=`grass --config python_path`:$PYTHONPATH - export LD_LIBRARY_PATH=$(grass --config path)/lib:$LD_LIBRARY_PATH - pylint --persistent=no --py-version=${{ env.MIN_PYTHON_VERSION }} --jobs=$(nproc) . + PYTHONPATH="$(grass --config python_path):$PYTHONPATH" + LD_LIBRARY_PATH="$(grass --config path)/lib:$LD_LIBRARY_PATH" + export PYTHONPATH + export LD_LIBRARY_PATH + pylint --persistent=no --py-version="${MIN_PYTHON_VERSION}" --jobs="$(nproc)" . - name: Test compiling example modules run: | diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml index c22d712e9a2..df68b160316 100644 --- a/.github/workflows/super-linter.yml +++ b/.github/workflows/super-linter.yml @@ -53,6 +53,8 @@ jobs: # VALIDATE_CSS: true # VALIDATE_DOCKER: true VALIDATE_EDITORCONFIG: true + VALIDATE_GITHUB_ACTIONS: true + VALIDATE_GITHUB_ACTIONS_ZIZMOR: true VALIDATE_JAVASCRIPT_ES: true # VALIDATE_JAVASCRIPT_STANDARD: true VALIDATE_JSON: true diff --git a/.github/workflows/titles.yml b/.github/workflows/titles.yml index af815dffac6..6482e04cca6 100644 --- a/.github/workflows/titles.yml +++ b/.github/workflows/titles.yml @@ -2,7 +2,10 @@ name: Validate Titles on: + # zizmor: ignore[dangerous-triggers] Limits to maintained main branch, and avoids running PR code pull_request_target: + branches: + - main types: - edited # The following types are default for pull_request_target diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 23f7dd0e21b..3e0163d09ba 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -73,12 +73,13 @@ jobs: temporal testsuite utils vector visualization) echo "Complete set of folders that can be included:" echo "${array[@]}" - delete=( ${{ env.DELETE_ARRAY }} ) + # shellcheck disable=SC2206 + delete=( ${DELETE_ARRAY} ) echo "Included folders to remove from the complete set:" echo "${delete[@]}" for target in "${delete[@]}"; do for i in "${!array[@]}"; do - if [[ ${array[i]} = $target ]]; then + if [[ ${array[i]} = "${target}" ]]; then unset 'array[i]' fi done @@ -98,10 +99,10 @@ jobs: - name: Add extra exclusions to a gunittest config file run: | - sed 's:exclude =:exclude = ${{ - steps.get-exclude.outputs.extra-exclude - }}:g' .gunittest.cfg > .gunittest.extra.cfg + sed "s:exclude =:exclude = ${STEPS_GET_EXCLUDE_OUTPUTS_EXTRA_EXCLUDE}:g" .gunittest.cfg > .gunittest.extra.cfg cat .gunittest.extra.cfg + env: + STEPS_GET_EXCLUDE_OUTPUTS_EXTRA_EXCLUDE: ${{ steps.get-exclude.outputs.extra-exclude }} - name: Get dependencies run: | @@ -112,15 +113,15 @@ jobs: - name: Create installation directory run: | - mkdir $HOME/install + mkdir "${HOME}/install" - name: Set number of cores for compilation run: | - echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV + echo "MAKEFLAGS=-j$(nproc)" >> "${GITHUB_ENV}" - name: Set LD_LIBRARY_PATH for compilation run: | - echo "LD_LIBRARY_PATH=$HOME/install/lib" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=${HOME}/install/lib" >> "${GITHUB_ENV}" - name: Print build environment variables shell: bash -el {0} @@ -135,11 +136,13 @@ jobs: CFLAGS: -fPIC -Wvla -ffp-contract=off # TODO: -pedantic-errors here won't compile CXXFLAGS: -fPIC -ffp-contract=off - run: .github/workflows/build_${{ matrix.config }}.sh $HOME/install -Werror + MATRIX_CONFIG: ${{ matrix.config }} + run: | + ".github/workflows/build_${MATRIX_CONFIG}.sh" "${HOME}/install" -Werror - name: Add the bin directory to PATH run: | - echo "$HOME/install/bin" >> $GITHUB_PATH + echo "${HOME}/install/bin" >> "${GITHUB_PATH}" - name: Print installed versions if: always() @@ -150,7 +153,7 @@ jobs: - name: Cache GRASS Sample Dataset id: cached-data - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 + uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 with: path: sample-data/nc_spm_full_v2alpha2.tar.gz key: nc_spm_full_v2alpha2.tar.gz @@ -160,11 +163,18 @@ jobs: if: steps.cached-data.outputs.cache-hit != 'true' run: | mkdir -p sample-data - curl -L "$SAMPLE_DATA" -o sample-data/nc_spm_full_v2alpha2.tar.gz + curl -L "${SAMPLE_DATA}" -o sample-data/nc_spm_full_v2alpha2.tar.gz env: SAMPLE_DATA: "https://grass.osgeo.org/sampledata/north_carolina/\ nc_spm_full_v2alpha2.tar.gz" + - name: Save GRASS Sample Dataset to cache + uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 + if: steps.cached-data.outputs.cache-hit != 'true' + with: + path: sample-data/nc_spm_full_v2alpha2.tar.gz + key: nc_spm_full_v2alpha2.tar.gz + - name: Run tests run: .github/workflows/test_thorough.sh --config .gunittest.extra.cfg env: diff --git a/.github/workflows/verify-success.yml b/.github/workflows/verify-success.yml index 2d357f6ddce..89f1cb11a14 100644 --- a/.github/workflows/verify-success.yml +++ b/.github/workflows/verify-success.yml @@ -84,50 +84,44 @@ jobs: - name: Set outputs for each job result type id: has-result run: | - echo "failure=${{ - contains(env.NEEDS_RESULT, 'failure') }}" >> "$GITHUB_OUTPUT" - echo "cancelled=${{ - contains(env.NEEDS_RESULT, 'cancelled') }}" >> "$GITHUB_OUTPUT" - echo "skipped=${{ - contains(env.NEEDS_RESULT, 'skipped') }}" >> "$GITHUB_OUTPUT" - echo "success=${{ - contains(env.NEEDS_RESULT, 'success') }}" >> "$GITHUB_OUTPUT" + { + echo "failure=${{ contains(env.NEEDS_RESULT, 'failure') }}" + echo "cancelled=${{ contains(env.NEEDS_RESULT, 'cancelled') }}" + echo "skipped=${{ contains(env.NEEDS_RESULT, 'skipped') }}" + echo "success=${{ contains(env.NEEDS_RESULT, 'success') }}" + } >> "$GITHUB_OUTPUT" env: NEEDS_RESULT: ${{ toJson(fromJson(inputs.needs_context).*.result) }} - name: Set exit codes for each job result type id: exit-code run: | - echo "failure=${{ inputs.fail_if_failure && - fromJson(steps.has-result.outputs.failure) && 1 || 0 - }}" >> "$GITHUB_OUTPUT" - echo "cancelled=${{ inputs.fail_if_cancelled && - fromJson(steps.has-result.outputs.cancelled) && 1 || 0 - }}" >> "$GITHUB_OUTPUT" - echo "skipped=${{ inputs.fail_if_skipped && - fromJson(steps.has-result.outputs.skipped) && 1 || 0 - }}" >> "$GITHUB_OUTPUT" - echo "success=${{ inputs.require_success && - !fromJson(steps.has-result.outputs.success) && 1 || 0 - }}" >> "$GITHUB_OUTPUT" + { + echo "failure=${{ inputs.fail_if_failure && + fromJson(steps.has-result.outputs.failure) && 1 || 0 }}" + echo "cancelled=${{ inputs.fail_if_cancelled && + fromJson(steps.has-result.outputs.cancelled) && 1 || 0 }}" + echo "skipped=${{ inputs.fail_if_skipped && + fromJson(steps.has-result.outputs.skipped) && 1 || 0 }}" + echo "success=${{ inputs.require_success && + !fromJson(steps.has-result.outputs.success) && 1 || 0 }}" + } >> "$GITHUB_OUTPUT" - name: Set messages for each job result type id: message run: | - echo "failure=${{ format('{0}{1} were failed', - (steps.exit-code.outputs.failure == 1) && env.P1 || env.P2, - (steps.has-result.outputs.failure == 'true') && env.M1 || env.M2) - }}" >> "$GITHUB_OUTPUT" - echo "cancelled=${{ format('{0}{1} were cancelled', - (steps.exit-code.outputs.cancelled == 1) && env.P1 || env.P2, - (steps.has-result.outputs.cancelled == 'true') && env.M1 || env.M2) - }}" >> "$GITHUB_OUTPUT" - echo "skipped=${{ format('{0}{1} were skipped', - (steps.exit-code.outputs.skipped == 1) && env.P1 || env.P2, - (steps.has-result.outputs.skipped == 'true') && env.M1 || env.M2) - }}" >> "$GITHUB_OUTPUT" - echo "success=${{ format('{0}{1} were successful', - (steps.exit-code.outputs.success == 1) && env.P1 || env.P2, - (steps.has-result.outputs.success == 'true') && env.M1 || env.M2) - }}" >> "$GITHUB_OUTPUT" + { + echo "failure=${{ format('{0}{1} were failed', + (steps.exit-code.outputs.failure == 1) && env.P1 || env.P2, + (steps.has-result.outputs.failure == 'true') && env.M1 || env.M2)}}" + echo "cancelled=${{ format('{0}{1} were cancelled', + (steps.exit-code.outputs.cancelled == 1) && env.P1 || env.P2, + (steps.has-result.outputs.cancelled == 'true') && env.M1 || env.M2)}}" + echo "skipped=${{ format('{0}{1} were skipped', + (steps.exit-code.outputs.skipped == 1) && env.P1 || env.P2, + (steps.has-result.outputs.skipped == 'true') && env.M1 || env.M2)}}" + echo "success=${{ format('{0}{1} were successful', + (steps.exit-code.outputs.success == 1) && env.P1 || env.P2, + (steps.has-result.outputs.success == 'true') && env.M1 || env.M2)}}" + } >> "$GITHUB_OUTPUT" env: P1: "::error ::" # Common message prefix if step will fail P2: "" # Common message prefix if step will not fail @@ -136,20 +130,32 @@ jobs: - name: Check for failed jobs run: | - echo "${{ steps.message.outputs.failure }}" - exit ${{ steps.exit-code.outputs.failure }} + echo "${STEPS_MESSAGE_OUTPUTS_FAILURE}" + exit "${STEPS_EXIT_CODE_OUTPUTS_FAILURE}" + env: + STEPS_MESSAGE_OUTPUTS_FAILURE: ${{ steps.message.outputs.failure }} + STEPS_EXIT_CODE_OUTPUTS_FAILURE: ${{ steps.exit-code.outputs.failure }} - name: Check for cancelled jobs run: | - echo "${{ steps.message.outputs.cancelled }}" - exit ${{ steps.exit-code.outputs.cancelled }} + echo "${STEPS_MESSAGE_OUTPUTS_CANCELLED}" + exit "${STEPS_EXIT_CODE_OUTPUTS_CANCELLED}" + env: + STEPS_MESSAGE_OUTPUTS_CANCELLED: ${{ steps.message.outputs.cancelled }} + STEPS_EXIT_CODE_OUTPUTS_CANCELLED: ${{ steps.exit-code.outputs.cancelled }} - name: Check for skipped jobs run: | - echo "${{ steps.message.outputs.skipped }}" - exit ${{ steps.exit-code.outputs.skipped }} + echo "${STEPS_MESSAGE_OUTPUTS_SKIPPED}" + exit "${STEPS_EXIT_CODE_OUTPUTS_SKIPPED}" + env: + STEPS_MESSAGE_OUTPUTS_SKIPPED: ${{ steps.message.outputs.skipped }} + STEPS_EXIT_CODE_OUTPUTS_SKIPPED: ${{ steps.exit-code.outputs.skipped }} - name: Check for successful jobs run: | - echo "${{ steps.message.outputs.success }}" - exit ${{ steps.exit-code.outputs.success }} + echo "${STEPS_MESSAGE_OUTPUTS_SUCCESS}" + exit "${STEPS_EXIT_CODE_OUTPUTS_SUCCESS}" + env: + STEPS_MESSAGE_OUTPUTS_SUCCESS: ${{ steps.message.outputs.success }} + STEPS_EXIT_CODE_OUTPUTS_SUCCESS: ${{ steps.exit-code.outputs.success }} - run: echo "Checks passed successfully" if: ${{ success() }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fe28086806b..bb1e9974fb6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -77,6 +77,14 @@ repos: rev: v1.37.1 hooks: - id: yamllint + - repo: https://github.com/rhysd/actionlint + rev: v1.7.7 + hooks: + - id: actionlint + - repo: https://github.com/zizmorcore/zizmor-pre-commit + rev: v1.12.1 + hooks: + - id: zizmor - repo: https://github.com/editorconfig-checker/editorconfig-checker rev: v3.4.0 hooks: