Skip to content

Commit 0680c92

Browse files
committed
Merge remote-tracking branch 'upstream' into merge-master-march
2 parents 02725ff + fd9458d commit 0680c92

File tree

205 files changed

+11423
-5896
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

205 files changed

+11423
-5896
lines changed

.git-blame-ignore-revs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: : 2022 The PyPSA-Eur Authors
1+
# SPDX-FileCopyrightText: Contributors to PyPSA-Eur <https://github.com/pypsa/pypsa-eur>
22
#
33
# SPDX-License-Identifier: CC0-1.0
44

@@ -8,6 +8,9 @@
88

99
# Custom commits
1010
9865a970893d9e515786f33c629b14f71645bf1e
11+
6a974d0bba5f6d45957f0196b77fd49dbbbbf777
12+
151dc73b40dfbe78ba08d5698b39b1cf2e5a5ff5
13+
1114
# DE model specific
1215
ca1f43c23f1c0936cb9f9e1062854fdf0060c409
1316

.gitattributes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: : 2017-2024 The PyPSA-Eur Authors
1+
# SPDX-FileCopyrightText: Contributors to PyPSA-Eur <https://github.com/pypsa/pypsa-eur>
22
#
33
# SPDX-License-Identifier: CC0-1.0
44

.github/workflows/push-images.yaml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Push images
2+
3+
on:
4+
push:
5+
6+
branches:
7+
- master
8+
workflow_dispatch:
9+
10+
env:
11+
IMAGE_NAME: pypsa/eur-dev-env
12+
BASE_ENV: envs/linux-pinned.yaml
13+
14+
jobs:
15+
push-image:
16+
name: dev-env
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
23+
- name: 'Get relevant env'
24+
run: |
25+
hash_last_changed=$(git log -1 --pretty=format:%H -- ${{ env.BASE_ENV }})
26+
echo "hash_last_changed=$hash_last_changed" >> $GITHUB_ENV
27+
28+
- name: 'Login to GitHub Container Registry'
29+
uses: docker/login-action@v3
30+
with:
31+
registry: ghcr.io
32+
username: ${{ github.repository_owner }}
33+
password: ${{ secrets.REGISTRY_TOKEN }}
34+
35+
- name: 'Build new image' # only build if the pinned envs file was modified
36+
if: env.hash_last_changed == github.sha || github.event_name == 'workflow_dispatch'
37+
run: |
38+
docker build . --file docker/dev-env/Dockerfile --tag ghcr.io/${{ env.IMAGE_NAME }}:${{ github.sha }}
39+
docker push ghcr.io/${{ env.IMAGE_NAME }}:${{ github.sha }}
40+
41+
# Add latest tag if on main branch
42+
if [ "${{ github.ref }}" == "refs/heads/master" ]; then
43+
docker tag ghcr.io/${{ env.IMAGE_NAME }}:${{ github.sha }} ghcr.io/${{ env.IMAGE_NAME }}:latest
44+
docker push ghcr.io/${{ env.IMAGE_NAME }}:latest
45+
fi
46+
47+
- name: 'Add SHA tag to existing image' # when rebuild is not needed
48+
if: env.hash_last_changed != github.sha
49+
run: |-
50+
docker pull ghcr.io/${{ env.IMAGE_NAME }}:${{ env.hash_last_changed }}
51+
docker tag ghcr.io/${{ env.IMAGE_NAME }}:${{ env.hash_last_changed }} ghcr.io/${{ env.IMAGE_NAME }}:${{ github.sha }}
52+
docker push ghcr.io/${{ env.IMAGE_NAME }}:${{ github.sha }}

.github/workflows/test.yaml

Lines changed: 69 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
# SPDX-FileCopyrightText: : 2021-2024 The PyPSA-Eur Authors
2-
#
3-
# SPDX-License-Identifier: CC0-1.0
4-
51
name: Test workflows
62

73
on:
@@ -12,28 +8,27 @@ on:
128
branches:
139
- main
1410
schedule:
15-
- cron: "0 5 * * *"
11+
- cron: "0 5 * * 1-6"
12+
- cron: "0 5 * * 0"
13+
workflow_dispatch:
1614

1715
# Cancel any in-progress runs when a new run is triggered
1816
concurrency:
1917
group: ${{ github.workflow }}-${{ github.ref }}
2018
cancel-in-progress: true
2119

2220
env:
23-
ENV_FILE: envs/environment.yaml
24-
ENV_FIXED_FILE: envs/environment.fixed.yaml
21+
BASE_ENV: envs/environment.yaml
2522

2623
jobs:
2724
run-tests:
2825
name: OS
26+
runs-on: ${{ matrix.os }}-latest
2927
strategy:
3028
fail-fast: false
3129
matrix:
32-
os:
33-
- macos
34-
- windows
35-
- ubuntu
36-
runs-on: ${{ matrix.os }}-latest
30+
# Run windows only on scheduled runs on Sundays, otherwise ignore
31+
os: ${{ github.event.schedule == '0 5 * * 0' && fromJson('["ubuntu", "macos", "windows"]') || fromJson('["ubuntu", "macos"]') }}
3732

3833
defaults:
3934
run:
@@ -42,73 +37,83 @@ jobs:
4237
steps:
4338
- uses: actions/checkout@v4
4439

45-
- name: Setup secrets & cache dates
40+
- name: Setup env file path (ubuntu)
41+
if: matrix.os == 'ubuntu'
42+
run: |
43+
echo "env_file=envs/linux-pinned.yaml" >> $GITHUB_ENV
44+
45+
- name: Setup env file path (macos and windows)
46+
if: matrix.os != 'ubuntu'
47+
run: |
48+
echo "env_file=envs/${{ matrix.os }}-pinned.yaml" >> $GITHUB_ENV
49+
50+
- name: Use base env file if it was changed
4651
run: |
47-
echo -ne "url: ${CDSAPI_URL}\nkey: ${CDSAPI_TOKEN}\n" > ~/.cdsapirc
48-
echo "week=$(date +'%Y%U')" >> $GITHUB_ENV # data and cutouts
49-
echo "today=$(/bin/date -u '+%Y%m%d')" >> $GITHUB_ENV # env
52+
git fetch origin master
53+
if git diff --name-only origin/master | grep '${{ env.BASE_ENV }}'; then
54+
echo "Base env ${{ env.BASE_ENV }} changed. Using it instead of pinned envs."
55+
echo "env_file=${{ env.BASE_ENV }}" >> $GITHUB_ENV
56+
else
57+
echo "Base env ${{ env.BASE_ENV }} not changed. Using pinned envs."
58+
fi
59+
60+
- name: Setup cache keys
61+
run: |
62+
echo "WEEK=$(date +'%Y%U')" >> $GITHUB_ENV # data and cutouts
5063
5164
- uses: actions/cache@v4
5265
with:
5366
path: |
5467
data
5568
cutouts
56-
key: data-cutouts-${{ env.week }}
69+
key: data-cutouts-${{ env.WEEK }}
5770

5871
- uses: conda-incubator/setup-miniconda@v3
5972
with:
73+
miniforge-version: latest
6074
activate-environment: pypsa-eur
75+
channel-priority: strict
6176

6277
- name: Cache Conda env
6378
uses: actions/cache@v4
6479
with:
6580
path: ${{ env.CONDA }}/envs
66-
key: conda-${{ runner.os }}-${{ runner.arch }}-${{ env.today }}-${{ hashFiles(format('{0}', env.ENV_FILE)) }}
81+
key: conda-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles(format('{0}', env.env_file)) }}
6782
id: cache-env
6883

6984
- name: Update environment
7085
if: steps.cache-env.outputs.cache-hit != 'true'
71-
run: conda env update -n pypsa-eur -f ${{ env.ENV_FILE }}
72-
73-
- name: Log env diff to environment.fixed.yaml
74-
if: ${{ matrix.os == 'ubuntu' }}
7586
run: |
76-
# Get fixed environment of current env
77-
conda env export --name ${{ github.event.repository.name }} --no-builds | sed 's/^name: ${{ github.event.repository.name }}$/name: ${{ github.event.repository.name }}-fixed/' > current-env.yaml
78-
79-
# Add SPDX header
80-
SPDX_HEADER="# SPDX-FileCopyrightText: : 2017-2024 The PyPSA-Eur Authors\n# SPDX-License-Identifier: CC0-1.0\n"
81-
echo -e "$SPDX_HEADER" | cat - current-env.yaml > temp && mv temp current-env.yaml
82-
83-
# Format with pre-commit (it differs from the conda output)
84-
pip install pre-commit
85-
pre-commit run --files current-env.yaml || true
87+
conda env update -n pypsa-eur -f ${{ env.env_file }}
88+
echo "Run conda list" && conda list
8689
87-
# Get diff
88-
diff ${{ env.ENV_FIXED_FILE }} current-env.yaml > diff.txt || true
89-
90-
# Format
91-
{ echo -e "**Environment diff**\n\`\`\` diff\n"; cat diff.txt; echo -e "\n\`\`\`"; } > temp && mv temp diff.txt
92-
93-
# Write to summary
94-
cat diff.txt >> $GITHUB_STEP_SUMMARY
95-
shell: bash
90+
- name: Run pylint check on scripts
91+
# check for undefined variables to reuse functions across scripts
92+
run: |
93+
pylint --disable=all --enable=E0601 --output-format=parseable scripts/add_* scripts/prepare_* scripts/solve_*
9694
9795
- name: Run snakemake test workflows
9896
run: |
9997
make test
10098
99+
- name: Run unit tests
100+
run: |
101+
make unit-test
102+
101103
- name: Upload artifacts
104+
if: always()
102105
uses: actions/upload-artifact@v4
103106
with:
104-
name: logs-${{ matrix.inhouse }}
107+
name: results-${{ matrix.os }}
105108
path: |
106109
logs
107110
.snakemake/log
111+
results
108112
retention-days: 3
109113

110114
run-tests-on-dev-deps:
111115
name: Inhouse
116+
runs-on: ubuntu-latest
112117
strategy:
113118
fail-fast: false
114119
matrix:
@@ -117,7 +122,6 @@ jobs:
117122
- atlite
118123
- powerplantmatching
119124
- linopy
120-
runs-on: ubuntu-latest
121125

122126
defaults:
123127
run:
@@ -126,30 +130,39 @@ jobs:
126130
steps:
127131
- uses: actions/checkout@v4
128132

133+
- name: Use base env file if it was changed
134+
run: |
135+
git fetch origin master
136+
if git diff --name-only origin/master | grep '${{ env.BASE_ENV }}'; then
137+
echo "Base env ${{ env.BASE_ENV }} changed. Using it instead of pinned envs."
138+
echo "env_file=${{ env.BASE_ENV }}" >> $GITHUB_ENV
139+
else
140+
echo "Base env ${{ env.BASE_ENV }} not changed. Using pinned envs."
141+
echo "env_file=envs/linux-pinned.yaml" >> $GITHUB_ENV
142+
fi
143+
129144
# Only run checks if package is not pinned
130145
- name: Check if inhouse package is pinned
131146
run: |
132-
grep_line=$(grep -- '- ${{ matrix.inhouse }}' ${{ env.ENV_FILE }})
147+
grep_line=$(grep -- '- ${{ matrix.inhouse }}' ${{ env.BASE_ENV }})
133148
if [[ $grep_line == *"<"* || $grep_line == *"=="* ]]; then
134149
echo "pinned=true" >> $GITHUB_ENV
135150
else
136151
echo "pinned=false" >> $GITHUB_ENV
137152
fi
138153
139-
- name: Setup secrets & cache dates
154+
- name: Setup cache keys
140155
if: env.pinned == 'false'
141156
run: |
142-
echo -ne "url: ${CDSAPI_URL}\nkey: ${CDSAPI_TOKEN}\n" > ~/.cdsapirc
143-
echo "week=$(date +'%Y%U')" >> $GITHUB_ENV # data and cutouts
144-
echo "today=$(/bin/date -u '+%Y%m%d')" >> $GITHUB_ENV # env
157+
echo "WEEK=$(date +'%Y%U')" >> $GITHUB_ENV # data and cutouts
145158
146159
- uses: actions/cache@v4
147160
if: env.pinned == 'false'
148161
with:
149162
path: |
150163
data
151164
cutouts
152-
key: data-cutouts-${{ env.week }}
165+
key: data-cutouts-${{ env.WEEK }}
153166

154167
- uses: conda-incubator/setup-miniconda@v3
155168
if: env.pinned == 'false'
@@ -161,12 +174,14 @@ jobs:
161174
uses: actions/cache@v4
162175
with:
163176
path: ${{ env.CONDA }}/envs
164-
key: conda-${{ runner.os }}-${{ runner.arch }}-${{ matrix.inhouse }}-${{ env.today }}-${{ hashFiles(format('{0}', env.ENV_FILE)) }}
177+
key: conda-${{ runner.os }}-${{ runner.arch }}-${{ matrix.inhouse }}-${{ hashFiles(format('{0}', env.env_file)) }}
165178
id: cache-env
166179

167180
- name: Update environment
168181
if: env.pinned == 'false' && steps.cache-env.outputs.cache-hit != 'true'
169-
run: conda env update -n pypsa-eur -f ${{ env.ENV_FILE }}
182+
run: |
183+
conda env update -n pypsa-eur -f ${{ env.env_file }}
184+
echo "Run conda list" && conda list
170185
171186
- name: Install inhouse packages from master
172187
if: env.pinned == 'false'
@@ -179,11 +194,12 @@ jobs:
179194
make test
180195
181196
- name: Upload artifacts
182-
if: env.pinned == 'false'
197+
if: env.pinned == 'false' && always()
183198
uses: actions/upload-artifact@v4
184199
with:
185-
name: logs-${{ matrix.inhouse }}
200+
name: results-inhouse-${{ matrix.inhouse }}
186201
path: |
187202
logs
188203
.snakemake/log
204+
results
189205
retention-days: 3

.github/workflows/update-pinned-env.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ jobs:
3434
- name: Setup conda
3535
uses: conda-incubator/setup-miniconda@v3
3636
with:
37+
miniforge-version: latest
3738
activate-environment: ${{ github.event.repository.name }}
38-
channels: bioconda,conda-forge,defaults
39+
channel-priority: strict
3940
environment-file: ${{ env.BASE_ENV }}
4041

4142
- name: Update pinned environment per OS
@@ -83,5 +84,8 @@ jobs:
8384
token: ${{ secrets.GITHUB_TOKEN }}
8485
branch: update-pinned-environment
8586
title: "[github-actions.ci] Update pinned envs"
86-
body: "Automatically generated PR to update pinned environment files for Windows, macOS, and Linux."
87+
body: |
88+
Automatically generated PR to update pinned environment files for Windows, macOS, and Linux.
89+
90+
**Note: Do not merge without manual test execution. Either update the branch to trigger tests, or use `workflow_dispatch` to run tests manually. Unlike standard PRs, tests will not run automatically.**
8791
commit-message: "Update pinned environment files for all platforms"

.github/workflows/validate.yaml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ on:
44
pull_request:
55
branches:
66
- master
7-
- main
87

98
concurrency:
109
group: ${{ github.workflow }}-${{ github.ref }}
@@ -15,8 +14,12 @@ jobs:
1514
name: Run validation
1615
if: github.event.pull_request.head.repo.full_name == github.repository
1716
runs-on: self-hosted
17+
outputs:
18+
validation_failed: ${{ steps.check_validation.outputs.failed }}
1819
steps:
1920
- uses: PyPSA/pypsa-validator@v0.2.5
21+
id: validation
22+
continue-on-error: true
2023
with:
2124
step: run-self-hosted-validation
2225
env_file: envs/environment.yaml
@@ -25,11 +28,21 @@ jobs:
2528
main_command: "ariadne_all"
2629
env:
2730
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31+
- name: Check validation status
32+
id: check_validation
33+
run: |
34+
if [[ "${{ steps.validation.outcome }}" == "failure" ]]; then
35+
echo "failed=true" >> $GITHUB_OUTPUT
36+
else
37+
echo "failed=false" >> $GITHUB_OUTPUT
38+
fi
2839
2940
create-report:
3041
name: Create report
31-
if: github.event.pull_request.head.repo.full_name == github.repository
3242
needs: run-validation
43+
if: |
44+
github.event.pull_request.head.repo.full_name == github.repository &&
45+
needs.run-validation.outputs.validation_failed != 'true'
3346
runs-on: ubuntu-latest
3447
steps:
3548
- uses: PyPSA/pypsa-validator@v0.2.5

0 commit comments

Comments
 (0)