Skip to content

CI: Artifacts upload check v1 #158

CI: Artifacts upload check v1

CI: Artifacts upload check v1 #158

Workflow file for this run

---
name: macOS
# Build and run tests on macOS
on:
push:
branches:
- priotestci
pull_request:
branches:
- priotestci
env:
CACHE_NUMBER: 0
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
cancel-in-progress: true
permissions:
actions: read # Allows Github to fetch artifacts
jobs:
macos_build:
name: macOS build
runs-on: macos-15
env:
PYTHONWARNINGS: always
steps:
- name: Info
run: |
echo "macOS version $(sw_vers -productVersion)"
echo "architecture $(uname -a)"
- name: Disabling Spotlight
run: sudo mdutil -a -i off
- name: Uninstalling Homebrew
run: |
echo "Moving directories..."
sudo mkdir /opt/local-off /opt/homebrew-off
test ! -d /usr/local || /usr/bin/sudo /usr/bin/find /usr/local \
-mindepth 1 -maxdepth 1 -type d -print -exec /bin/mv {} \
/opt/local-off/ \;
test ! -d /opt/homebrew || /usr/bin/sudo /usr/bin/find /opt/homebrew \
-mindepth 1 -maxdepth 1 -type d -print -exec /bin/mv {} \
/opt/homebrew-off/ \;
echo "Removing files..."
test ! -d /usr/local || /usr/bin/sudo /usr/bin/find /usr/local \
-mindepth 1 -maxdepth 1 -type f -print -delete
test ! -d /opt/homebrew || /usr/bin/sudo /usr/bin/find /opt/homebrew \
-mindepth 1 -maxdepth 1 -type f -print -delete
# Rehash to forget about the deleted files
hash -r
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Get current date cache key segment
id: date
# Year and week of year so cache key changes weekly
run: echo "date=$(date +%Y-%U)" >> "${GITHUB_OUTPUT}"
- name: Prepare Conda environment file
env:
test_dependencies: |
ipython
pytest
pytest-github-actions-annotate-failures
pytest-timeout
pytest-xdist
pyyaml
run: |
cp ./macos/files/conda-requirements-dev-arm64.txt "${RUNNER_TEMP}/macos_dependencies.txt"
echo "${test_dependencies// /\n}" >> "${RUNNER_TEMP}/macos_dependencies.txt"
- name: Setup Mamba
uses: mamba-org/setup-micromamba@add3a49764cedee8ee24e82dfde87f5bc2914462 # v2.0.7
with:
init-shell: bash
environment-file: ${{ runner.temp }}/macos_dependencies.txt
environment-name: grass-env
# Persist on the same period (date).
cache-environment-key: environment-${{ steps.date.outputs.date }}
- name: Environment info
shell: bash -el {0}
run: |
printenv | sort
$CC --version
- name: Create installation directory
run: mkdir "${HOME}/install"
- name: Build and install
shell: micromamba-shell {0}
run: source ./.github/workflows/macos_install.sh "${HOME}/install"
- name: Add the bin directory to PATH
run: echo "${HOME}/install/bin" >> "${GITHUB_PATH}"
- name: Check installed version
if: ${{ !cancelled() }}
shell: micromamba-shell {0}
run: source ./.github/workflows/print_versions.sh
- name: Get PR ID
shell: bash
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "PR_ID=${{ github.event.number }}" >> "$GITHUB_ENV"
echo "This run is for PR #${{ github.event.number }}"
else
echo "PR_ID=none" >> "$GITHUB_ENV"
echo "This run is not a PR (branch: ${GITHUB_REF_NAME})"
fi
- name: Install jq in micromamba env
shell: micromamba-shell {0}
run: micromamba install -y jq
- name: Install pytest-json-report
shell: micromamba-shell {0}
run: python -m pip install --upgrade pytest-json-report
- name: Check If Previous Artifacts Exist
id: check_artifacts
shell: micromamba-shell {0}
run: |
echo "Checking if previous artifacts exist for PR-${PR_ID}..."
ARTIFACTS_RESPONSE=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${{ github.repository }}/actions/artifacts")
ARTIFACT_COUNT=$(echo "$ARTIFACTS_RESPONSE" \
| jq -r --arg NAME "pr_${PR_ID}_macos_smoketest" \
'[.artifacts[] | select(.name==$NAME and .expired==false)] | length')
echo "Found ${ARTIFACT_COUNT} matching artifact(s)."
if [[ "$ARTIFACT_COUNT" -gt 0 ]]; then
echo "PREV_ARTIFACT_EXISTS=true" >> "$GITHUB_ENV"
else
echo "PREV_ARTIFACT_EXISTS=false" >> "$GITHUB_ENV"
fi
- name: Create smoketest file (pr_<id>/macos)
shell: bash
run: |
PR_DIR="pr_${PR_ID}"
mkdir -p "artifacts/${PR_DIR}/macos"
{
echo "workflow: macOS"
echo "event: ${{ github.event_name }}"
echo "branch: ${GITHUB_REF_NAME}"
echo "pr_id: ${PR_ID}"
echo "timestamp: $(date -Iseconds)"
} > "artifacts/${PR_DIR}/macos/smoketest.txt"
- name: Upload smoketest artifact
uses: actions/upload-artifact@v4
with:
name: pr_${{ env.PR_ID }}_macos_smoketest
path: artifacts/pr_${{ env.PR_ID }}/macos/smoketest.txt
retention-days: 3
- name: Download smoketest artifact (to verify upload)
uses: actions/download-artifact@v4
with:
name: pr_${{ env.PR_ID }}_macos_smoketest
path: retrieved
- name: Show downloaded artifact contents
shell: bash
run: |
echo "==== Retrieved Artifact Files ===="
find retrieved -type f
echo "----------------------------------"
echo "Content of smoketest.txt:"
cat retrieved/smoketest.txt || echo "No smoketest file found."
# - name: Run pytest with multiple workers in parallel
# shell: micromamba-shell {0}
# run: |
# 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 \
# --junitxml=pytest.xdist.junit.xml \
# -k 'not testsuite'
- name: Check If Previous macOS Parallel Artifacts Exist
shell: micromamba-shell {0}
run: |
echo "Checking previous artifacts for PR-${PR_ID}..."
ARTIFACTS_RESPONSE=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${{ github.repository }}/actions/artifacts")
ARTIFACT_COUNT=$(echo "$ARTIFACTS_RESPONSE" \
| jq -r --arg NAME "pr_${PR_ID}_macos_parallel_results" \
'[.artifacts[] | select(.name==$NAME and .expired==false)] | length')
echo "Found ${ARTIFACT_COUNT} matching artifact(s)."
if [[ "$ARTIFACT_COUNT" -gt 0 ]]; then
echo "PREV_ARTIFACT_EXISTS=true" >> "$GITHUB_ENV"
else
echo "PREV_ARTIFACT_EXISTS=false" >> "$GITHUB_ENV"
fi
- name: Retrieve Previous macOS Parallel Artifacts
if: env.PREV_ARTIFACT_EXISTS == 'true'
shell: micromamba-shell {0}
run: |
echo "Retrieving previous macOS parallel results for PR-${PR_ID}..."
ARTIFACT_URL=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${{ github.repository }}/actions/artifacts" \
| jq -r --arg NAME "pr_${PR_ID}_macos_parallel_results" \
'[.artifacts[] | select(.name==$NAME)] | sort_by(.created_at) | reverse | .[0].archive_download_url')
if [[ -z "$ARTIFACT_URL" || "$ARTIFACT_URL" == "null" ]]; then
echo "Artifact URL not found."
exit 0
fi
mkdir -p artifacts/pr_${PR_ID}/macos_prev
curl -L -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-o artifacts/pr_${PR_ID}/macos_prev/results.zip "$ARTIFACT_URL"
unzip -o artifacts/pr_${PR_ID}/macos_prev/results.zip -d artifacts/pr_${PR_ID}/macos_prev
echo "===== Previous macOS parallel test results ====="
cat artifacts/pr_${PR_ID}/macos_prev/test_results.json || echo "No previous JSON found"
echo "================================================"
- name: Run previously failed tests first (macOS)
shell: micromamba-shell {0}
run: |
PYTHONPATH="$(grass --config python_path):${PYTHONPATH}"
LD_LIBRARY_PATH="$(grass --config path)/lib:${LD_LIBRARY_PATH}"
export PYTHONPATH
export LD_LIBRARY_PATH
PR_DIR="pr_${PR_ID}"
PREV_DIR="artifacts/${PR_DIR}/macos_prev"
CURR_DIR="artifacts/${PR_DIR}/macos"
mkdir -p "${CURR_DIR}"
FAILED_TESTS_FILE="${PREV_DIR}/failed_tests.txt"
TEMP_RESULTS="${CURR_DIR}/temp_test_results.json"
if [[ -s "${FAILED_TESTS_FILE}" ]]; then
echo "Re-running previously failed tests first:"
cat "${FAILED_TESTS_FILE}"
pytest \
@.github/workflows/pytest_args_ci.txt \
@.github/workflows/pytest_args_parallel.txt \
--json-report --json-report-file="${TEMP_RESULTS}" \
$(cat "${FAILED_TESTS_FILE}") || true
else
echo "No previously failed tests found."
# create empty JSON file so next steps never break
echo '{"tests": []}' > "${TEMP_RESULTS}"
fi
- name: Check if any tests failed again (macOS)
shell: micromamba-shell {0}
run: |
PR_DIR="pr_${PR_ID}"
CURR_DIR="artifacts/${PR_DIR}/macos"
TEMP_RESULTS="${CURR_DIR}/temp_test_results.json"
FAILED_AGAIN_FILE="${CURR_DIR}/failed_again.txt"
if [[ -f "${TEMP_RESULTS}" ]]; then
echo "Checking if any previously failed tests are still failing..."
jq -r '.tests | map(select(.outcome == "failed")) | .[].nodeid' \
"${TEMP_RESULTS}" > "${FAILED_AGAIN_FILE}" || true
else
echo "No temp JSON results found, assuming no tests failed again."
: > "${FAILED_AGAIN_FILE}"
fi
if [[ -s "${FAILED_AGAIN_FILE}" ]]; then
echo "Some tests failed again. Stopping execution."
echo "Tests failing again:"
cat "${FAILED_AGAIN_FILE}"
exit 1
else
echo "No tests failed again. Continuing with remaining tests..."
fi
- name: Collect all test cases (parallel macOS)
shell: micromamba-shell {0}
run: |
PYTHONPATH="$(grass --config python_path):${PYTHONPATH}"
LD_LIBRARY_PATH="$(grass --config path)/lib:${LD_LIBRARY_PATH}"
export PYTHONPATH
export LD_LIBRARY_PATH
PR_DIR="pr_${PR_ID}"
mkdir -p "artifacts/${PR_DIR}/macos"
pytest \
@.github/workflows/pytest_args_ci.txt \
@.github/workflows/pytest_args_parallel.txt \
--collect-only --quiet \
-k 'not testsuite' \
| grep "::" > "artifacts/${PR_DIR}/macos/all_tests.txt" || true
- name: Identify remaining tests to run (macOS)
shell: micromamba-shell {0}
run: |
PYTHONPATH="$(grass --config python_path):${PYTHONPATH}"
LD_LIBRARY_PATH="$(grass --config path)/lib:${LD_LIBRARY_PATH}"
export PYTHONPATH
export LD_LIBRARY_PATH
PR_DIR="pr_${PR_ID}"
PREV_DIR="artifacts/${PR_DIR}/macos_prev"
CURR_DIR="artifacts/${PR_DIR}/macos"
ALL_TESTS_FILE="${CURR_DIR}/all_tests.txt"
FAILED_PREV="${PREV_DIR}/failed_tests.txt"
REMAINING_TESTS_FILE="${CURR_DIR}/remaining_tests.txt"
mkdir -p "${CURR_DIR}"
if [[ -f "${FAILED_PREV}" && -s "${FAILED_PREV}" ]]; then
echo "Computing remaining tests (excluding previously failed ones)..."
grep -v -F -f "${FAILED_PREV}" "${ALL_TESTS_FILE}" > "${REMAINING_TESTS_FILE}" || true
else
echo "No previous failed tests list found or it is empty."
echo "Treating all collected tests as remaining."
cp "${ALL_TESTS_FILE}" "${REMAINING_TESTS_FILE}" || true
fi
echo "Remaining tests to run:"
cat "${REMAINING_TESTS_FILE}" || echo "No remaining tests found."
# - name: Run pytest with multiple workers in parallel (JSON report)
# shell: micromamba-shell {0}
# run: |
# PYTHONPATH="$(grass --config python_path):${PYTHONPATH}"
# LD_LIBRARY_PATH="$(grass --config path)/lib:${LD_LIBRARY_PATH}"
# export PYTHONPATH
# export LD_LIBRARY_PATH
# PR_DIR="pr_${PR_ID}"
# mkdir -p "artifacts/${PR_DIR}/macos"
# OUT_JSON="artifacts/${PR_DIR}/macos/test_results.json"
# pytest \
# @.github/workflows/pytest_args_ci.txt \
# @.github/workflows/pytest_args_parallel.txt \
# --junitxml=pytest.xdist.junit.xml \
# --json-report --json-report-file="${OUT_JSON}" \
# -k 'not testsuite' || true
- name: Run pytest with multiple workers in parallel (JSON report)
shell: micromamba-shell {0}
run: |
PYTHONPATH="$(grass --config python_path):${PYTHONPATH}"
LD_LIBRARY_PATH="$(grass --config path)/lib:${LD_LIBRARY_PATH}"
export PYTHONPATH
export LD_LIBRARY_PATH
PR_DIR="pr_${PR_ID}"
CURR_DIR="artifacts/${PR_DIR}/macos"
mkdir -p "${CURR_DIR}"
OUT_JSON="${CURR_DIR}/test_results.json"
REMAINING_TESTS_FILE="${CURR_DIR}/remaining_tests.txt"
if [[ -s "${REMAINING_TESTS_FILE}" ]]; then
echo "Running remaining test cases (macOS)..."
pytest \
@.github/workflows/pytest_args_ci.txt \
@.github/workflows/pytest_args_parallel.txt \
--junitxml=pytest.xdist.junit.xml \
--json-report --json-report-file="${OUT_JSON}" \
$(cat "${REMAINING_TESTS_FILE}") || true
else
echo "No remaining test cases to run. Writing empty JSON."
echo '{"tests": []}' > "${OUT_JSON}"
fi
- name: Extract failed and passed tests (parallel macOS)
shell: micromamba-shell {0}
run: |
PR_DIR="pr_${PR_ID}"
BASE_DIR="artifacts/${PR_DIR}/macos"
RESULTS="${BASE_DIR}/test_results.json"
FAILED="${BASE_DIR}/failed_tests.txt"
PASSED="${BASE_DIR}/passed_tests.txt"
if [[ -f "${RESULTS}" ]]; then
jq -r '.tests | map(select(.outcome == "failed")) | .[].nodeid' \
"${RESULTS}" > "${FAILED}" || true
jq -r '.tests | map(select(.outcome == "passed")) | .[].nodeid' \
"${RESULTS}" > "${PASSED}" || true
else
: > "${FAILED}"
: > "${PASSED}"
fi
echo "Failed tests:"
cat "${FAILED}" || true
echo "Passed tests:"
cat "${PASSED}" || true
- name: Upload macOS parallel test artifacts
uses: actions/upload-artifact@v4
with:
name: pr_${{ env.PR_ID }}_macos_parallel_results
path: |
artifacts/pr_${{ env.PR_ID }}/macos/all_tests.txt
artifacts/pr_${{ env.PR_ID }}/macos/failed_tests.txt
artifacts/pr_${{ env.PR_ID }}/macos/passed_tests.txt
artifacts/pr_${{ env.PR_ID }}/macos/test_results.json
retention-days: 7
- name: Run pytest with a single worker (for tests marked with needs_solo_run)
shell: micromamba-shell {0}
run: |
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 \
--junitxml=pytest.needs_solo_run.junit.xml \
-k 'not testsuite'
- name: Run pytest with a single worker (for gunittest-based tests)
shell: micromamba-shell {0}
run: |
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
- name: Upload test results to Codecov
if: ${{ !cancelled() }}
uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # v1.1.1
with:
exclude: gui
flags: macos-pytest-python
token: ${{ secrets.CODECOV_TOKEN }}
- name: Cache GRASS Sample Dataset
id: cached-data
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: sample-data/nc_spm_full_v2alpha2.tar.gz
key: nc_spm_full_v2alpha2.tar.gz
enableCrossOsArchive: true
- name: Download GRASS Sample Dataset
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
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@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
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
env:
SAMPLE_DATA_URL: "file://${{ github.workspace }}/sample-data/\
nc_spm_full_v2alpha2.tar.gz"
- name: Make HTML test report available
if: ${{ !cancelled() }}
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: testreport-macOS
path: testreport
retention-days: 3