Skip to content

Commit 862050e

Browse files
authored
Adding possiblity to use constant CO2 value (#132)
* Adding possiblity to use constant CO2 value * Added grid intensity constant test * Adapted tests to use new co2-calculation-method * Var was not assigned after removing bracket * Using new ECO_CI_CO2_GRID_INTENSITY_API_TOKEN * using different constant for world * Relaxing power values slightly * Relaxing power values more for high load * Typos, Indents and clarifications
1 parent 3752868 commit 862050e

File tree

12 files changed

+222
-83
lines changed

12 files changed

+222
-83
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
name: Test PR & Periodic
2+
3+
on:
4+
pull_request:
5+
paths-ignore:
6+
- 'README.md'
7+
- 'LICENSE'
8+
- '.gitlab-ci.yml.example'
9+
- '.gitignore'
10+
schedule:
11+
# only run once a week to show the action is working and preserve as much energy as possible
12+
# Reason being that we pull our ML model and this could have changed in the meantime
13+
- cron: '22 4 * * 6'
14+
workflow_dispatch:
15+
16+
permissions:
17+
contents: read
18+
actions: read
19+
pull-requests: write
20+
21+
jobs:
22+
test-action:
23+
runs-on: ubuntu-latest
24+
continue-on-error: false
25+
26+
steps:
27+
- uses: actions/checkout@v4
28+
with:
29+
path: .
30+
31+
- name: Initialize Energy Estimation
32+
uses: ./
33+
with:
34+
task: start-measurement
35+
project: "Eco CI"
36+
machine: "ubuntu-latest"
37+
tags: "CI/CD,Test PR & Periodic-Workflow"
38+
gmt-api-token: ${{ secrets.GMT_API_TOKEN }}
39+
40+
- name: working step
41+
continue-on-error: true
42+
run: |
43+
timeout 2s ls -alhR / || true
44+
45+
- name: Final Measurement no label
46+
uses: ./
47+
with:
48+
task: get-measurement
49+
50+
51+
- name: Eco CI Energy Estimation
52+
uses: ./
53+
with:
54+
task: display-results
55+
pr-comment: true
56+
57+
- name: Validate power values
58+
shell: bash
59+
run: |
60+
set -e
61+
min=1.75
62+
max=5.60
63+
64+
total_power=$(grep "<td>Total Run</td>" /tmp/eco-ci/output.txt | awk -F'</td><td>' '{print $4}')
65+
66+
awk -v p="$total_power" -v min="$min" -v max="$max" '
67+
BEGIN {
68+
if (p ~ /^[0-9.]+$/) {
69+
printf "Total power: %.2f\n", p
70+
if (p > min && p < max) {
71+
exit 0
72+
} else {
73+
exit 1
74+
}
75+
} else {
76+
print "Invalid power value"
77+
exit 1
78+
}
79+
}'
80+
81+
status=$?
82+
if [[ $status -eq 0 ]]; then
83+
echo "Power value is in the expected range [$min, $max]."
84+
else
85+
echo "Power value is outside the expected range [$min, $max]."
86+
exit 1
87+
fi
88+
89+
- name: Validate grid intensity
90+
shell: bash
91+
run: |
92+
if ! grep -q "472 gCO₂eq/kWh" /tmp/eco-ci/output.txt; then
93+
echo "Carbon intensity 472 gCO₂eq/kWh not found in /tmp/eco-ci/output.txt"
94+
exit 1
95+
fi

.github/workflows/data-json-test.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ jobs:
3030
machine: "ubuntu-latest"
3131
tags: "CI/CD,JSON-Workflow"
3232
gmt-api-token: ${{ secrets.GMT_API_TOKEN }}
33-
electricitymaps-api-token: ${{ secrets.ELECTRICITYMAPS_TOKEN }}
33+
co2-calculation-method: "location-based"
34+
co2-grid-intensity-api-token: ${{ secrets.ELECTRICITYMAPS_TOKEN }}
3435

3536
- uses: actions/setup-node@v4
3637
with:

.github/workflows/test.yml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ jobs:
5151
machine: ${{ matrix.os }}
5252
tags: "CI/CD,Test PR & Periodic-Workflow"
5353
gmt-api-token: ${{ secrets.GMT_API_TOKEN }}
54-
electricitymaps-api-token: ${{ secrets.ELECTRICITYMAPS_TOKEN }}
54+
co2-calculation-method: "location-based"
55+
co2-grid-intensity-api-token: ${{ secrets.ELECTRICITYMAPS_TOKEN }}
5556

5657
- name: Initialize Energy Estimation (macos-14)
5758
if: ${{ contains(matrix.os, 'macos-14') }}
@@ -62,7 +63,8 @@ jobs:
6263
machine: ${{ matrix.os }}
6364
tags: "CI/CD,Test PR & Periodic-Workflow"
6465
gmt-api-token: ${{ secrets.GMT_API_TOKEN }}
65-
electricitymaps-api-token: ${{ secrets.ELECTRICITYMAPS_TOKEN }}
66+
co2-calculation-method: "location-based"
67+
co2-grid-intensity-api-token: ${{ secrets.ELECTRICITYMAPS_TOKEN }}
6668
machine-power-data: "macos-14-mac-mini-m1.sh"
6769

6870
- name: Initialize Energy Estimation (macos-13)
@@ -74,7 +76,8 @@ jobs:
7476
machine: ${{ matrix.os }}
7577
tags: "CI/CD,Test PR & Periodic-Workflow"
7678
gmt-api-token: ${{ secrets.GMT_API_TOKEN }}
77-
electricitymaps-api-token: ${{ secrets.ELECTRICITYMAPS_TOKEN }}
79+
co2-calculation-method: "location-based"
80+
co2-grid-intensity-api-token: ${{ secrets.ELECTRICITYMAPS_TOKEN }}
7881
machine-power-data: "macos-13-mac-mini-intel.sh"
7982

8083

README.md

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Eco CI is a project aimed at estimating energy consumption in continuous integra
99
- [Usage](#usage)
1010
- [GitHub](#github)
1111
- [GitHub Action Mandatory and Optional Variables](#github-action-mandatory-and-optional-variables)
12-
- [Electricity Maps Token](#electricity-maps-token)
12+
- [Grid Intensity API Token](#grid-intensity-api-token)
1313
- [Continuing on Errors](#continuing-on-errors)
1414
- [Consuming the Measurements as JSON](#consuming-the-measurements-as-json)
1515
- [Note on Private Repos](#note-on-private-repos)
@@ -22,6 +22,7 @@ Eco CI is a project aimed at estimating energy consumption in continuous integra
2222
- [Trying out with Docker and Circle-CI image](#trying-out-with-docker-and-circle-ci-image)
2323
- [Trying out with Docker and KDE pipelines](#trying-out-with-docker-and-kde-pipelines)
2424
- [Jenkins](#jenkins)
25+
- [Restricted Enterprise Environments](#restricted-environments)
2526
- [Note on the integration / Auto-Updates](#note-on-the-integration-auto-updates)
2627
- [Limitations / Compatibility](#limitations--compatibility)
2728

@@ -123,16 +124,21 @@ jobs:
123124

124125
- `task`: (required) (options are `start-measurement`, `get-measurement`, `display-results`)
125126
+ `start-measurement`: Initialize the action and starts the measurement. This must be called, and only *once* per job. If called again data will be reset.
127+
- `co2-calculation-method`: (optional) (default: 'constant')
128+
- Can have the options `constant` or `location-based`
129+
- If you use `constant` you must also set `co2-grid-intensity-constant`
130+
- if you use `location-based` you must also set `co2-grid-intensity-api-token`
131+
- `co2-grid-intensity-constant`: (optional) (default: 472)
132+
- Constant value to be used to calculate the CO2 from the estimated energy.
133+
- We use the worldwide average value from Ember compiled by The Green Web Foundation from https://github.com/thegreenwebfoundation/co2.js/blob/main/data/output/average-intensities.json#L1314 as default and update it annually.
134+
- `co2-grid-intensity-api-token`: (optional)
135+
- API token for the API of your choice regarding the grid intensity. See details below under [Grid Intensity API Token](#grid-intensity-api-token) which APIs are currently supported.
136+
- Note that when using an API Eco CI also needs to resolve the location of the IP. Currently implemented via https://ipapi.co/
126137
- `branch`: (optional) (default: ${{ github.ref_name }})
127138
- Used to correctly identify this CI run for the Badge. Especially in PRs this will be very cryptic like `merge/72` and you might want to set this to something nicer
128139
- `label`: (optional) (default: 'measurement ##')
129140
- `send-data`: (optional) (default: true)
130141
- Send metrics data to metrics.green-coding.io to create and display badge, and see an overview of the energy of your CI runs. Set to false to send no data. The data we send are: the energy value and duration of measurement; cpu model; repository name/branch/workflow_id/run_id; commit_hash; source (GitHub or GitLab). We use this data to display in our green-metrics-tool front-end here: https://metrics.green-coding.io/ci-index.html
131-
- `calculate-co2`: (optional) (default: true)
132-
- You might typically always want this value to be shown unless you are in a restricted network and cannot make outbound requests
133-
- Gets the location using https://ipapi.co/
134-
- Get the CO2 grid intensity for the location from https://www.electricitymaps.com/
135-
- Estimates the amount of carbon the measurement has produced
136142
- `gh-api-base`: (optional) (default: 'api.github.com')
137143
- Eco CI uses the github api to post/edit PR comments and get the workflow id
138144
- set to github's default api, but can be changed if you are using github enterprise
@@ -150,8 +156,6 @@ jobs:
150156
- When using the GMT Dashboard and / or CarbonDB specify the endpoint URL to send to. Defaults to "https://api.green-coding.io/v2/ci/measurement/add"
151157
- `api-endpoint-badge-get`: (optional)
152158
- When using the GMT Dashboard and / or CarbonDB specify the endpoint URL to get the badge from to. Defaults to "https://api.green-coding.io//v1/ci/badge/get
153-
- `electricitymaps-api-token`: (optional)
154-
- API token for electricitymaps in case you get rate-limited. See details below.
155159
- `get-measurement`: Measures the energy at this point in time since either the start-measurement or last get-measurement action call.
156160
- `label`: (optional) (default: 'measurement ##')
157161

@@ -167,15 +171,26 @@ jobs:
167171
- `json-output`: (optional) (default: false)
168172
- will output data to JSON to `/tmp/eco-ci/lap-data.json`
169173

170-
#### Electricity Maps Token
174+
#### Grid Intensity API Token
175+
Used to get the grid intensity for a given location.
176+
We currently only support ElectricityMaps. WattTime and Entso-e are on the way! (Speed it up with a PR! ❤️)
177+
178+
##### ElectricityMaps
179+
It is free for personal use but sadly it is locked to a single zone. This means that if you get it for the Zone Germany the API will fail when requesting values for the US.
180+
181+
This is very problematic on GitHub Actions as the Us is comprised out of different zones and the machines come up in different zones. Either you buy a multi-zone key or you will have a lot of missing values.
171182

172-
We use ElectricityMaps to get the grid intensity for a given location.
173-
If you want carbon values to be displayed you must set this token. It is free for personal use. In case you need a commercial license it does not matter which zones you select, as we only use the real-time endpoint which is zone free.
174183
Get your key here: [https://api-portal.electricitymaps.com/](https://api-portal.electricitymaps.com/)
175184

176185
After having obtained the token you must set it as secret and pass it in the initalization of the action (see documentation above).
177186
To learn how to create a secret see the GitHub documentation: https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions
178187

188+
##### WattTime
189+
TODO - (Speed it up with a PR! ❤️)
190+
191+
##### Entso-e
192+
TODO - (Speed it up with a PR! ❤️)
193+
179194
#### Continuing on Errors
180195

181196
Once you have initially set up Eco CI and have given it a test spin we recommend running our action
@@ -471,6 +486,15 @@ export PATH="/opt/homebrew/opt/coreutils/libexec/gnubin:$PATH" # if macOS
471486
+ We do **not** recommend this as it might contain beta features. We recommend using the releases and tagged versions only
472487

473488

489+
## Restricted Environments
490+
If you are running in restricted environments, such as an enterprise with a heavily constrained network, you can tell Eco CI to not make any outbound requests.
491+
492+
Set:
493+
- `send-data` to `false`
494+
- Otherwise data will be sent to the API endpoint configured in `api-endpoint-add`
495+
- `co2-calculation-method` to `constant`
496+
- Otherwise the IP will be resolved to a location
497+
474498
## Limitations / Compatibility
475499
- At the moment this will only work with linux based pipelines, mainly tested on ubuntu images.
476500
+ The plugin is tested on:

action.yml

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ inputs:
2525
description: 'Send metrics data to dashboard (default: metrics.green-coding.io) to create and display badge, and see an overview of the energy of your CI runs. Set to false to send no data.'
2626
default: true
2727
required: false
28-
calculate-co2:
29-
description: 'Uses the grid carbon intensity of the run location to estimate the emitted carbon for the measurements.'
30-
default: true
31-
required: false
3228
display-table:
3329
description: 'Show the energy reading results in a table during display-results step'
3430
default: true
@@ -81,9 +77,16 @@ inputs:
8177
description: 'The URL for the GMT Dashboard. Punch in yours if self-hosted. Defaults to "https://metrics.green-coding.io"'
8278
default: 'https://metrics.green-coding.io'
8379
required: false
84-
85-
electricitymaps-api-token:
86-
description: 'API token for electricitymaps in case you get rate-limited. See documentation for details'
80+
co2-calculation-method:
81+
description: 'CO2 calculation can be a constant and will use a supplied fixed grid intensity. Or it can also be location based where it will use a grid intensity API provider to determine the carbon intensity value of the current machine IP.'
82+
default: 'constant'
83+
required: false
84+
co2-grid-intensity-constant:
85+
description: "Constant value to be used to calculate the CO2 from the estimated energy. We use the worldwide average value from Ember compiled by The Green Web Foundation from https://github.com/thegreenwebfoundation/co2.js/blob/main/data/output/average-intensities.json#L1314 as default and update it annually."
86+
default: 472
87+
required: false
88+
co2-grid-intensity-api-token:
89+
description: 'API token for the API of your choice regarding the grid intensity. See documentation for details'
8790
default: ''
8891
required: false
8992

@@ -120,7 +123,7 @@ runs:
120123
workflow_id=${workflow_id:-"not_set"}
121124
workflow_name=${workflow_name:-"not_set"}
122125
123-
${{github.action_path}}/scripts/setup.sh start_measurement "${{inputs.machine-power-data}}" "${{ github.run_id }}" "${{inputs.branch}}" "${{ github.repository }}" "$workflow_id" "$workflow_name" "${{ github.sha }}" "github" "${{ inputs.send-data }}" "${{ inputs.type }}" "${{ inputs.project }}" "${{ inputs.machine }}" "${{ inputs.tags }}" "${{ inputs.calculate-co2 }}" "${{ inputs.gmt-api-token }}" "${{ inputs.electricitymaps-api-token }}" "${{ inputs.json-output }}" "${{ inputs.api-endpoint-add }}" "${{ inputs.api-endpoint-badge-get }}" "${{ inputs.dashboard-url }}"
126+
${{github.action_path}}/scripts/setup.sh start_measurement "${{inputs.machine-power-data}}" "${{ github.run_id }}" "${{inputs.branch}}" "${{ github.repository }}" "$workflow_id" "$workflow_name" "${{ github.sha }}" "github" "${{ inputs.send-data }}" "${{ inputs.type }}" "${{ inputs.project }}" "${{ inputs.machine }}" "${{ inputs.tags }}" "${{ inputs.co2-calculation-method }}" "${{ inputs.co2-grid-intensity-constant }}" "${{ inputs.co2-grid-intensity-api-token }}" "${{ inputs.gmt-api-token }}" "${{ inputs.json-output }}" "${{ inputs.api-endpoint-add }}" "${{ inputs.api-endpoint-badge-get }}" "${{ inputs.dashboard-url }}"
124127
125128
- if: inputs.task == 'get-measurement'
126129
id: run-lap-model

eco-ci-gitlab.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ variables:
88
ECO_CI_FILTER_MACHINE: "saas-linux-small-amd64"
99
ECO_CI_FILTER_TAGS: ""
1010
ECO_CI_JSON_OUTPUT: "false"
11-
ECO_CI_CALCULATE_CO2: "true"
11+
ECO_CI_CO2_CALCULATION_METHOD: "constant"
12+
ECO_CI_CO2_GRID_INTENSITY_CONSTANT: 334 # for Germany in 2024 from https://app.electricitymaps.com/zone/DE/all/yearly
13+
ECO_CI_CO2_GRID_INTENSITY_API_TOKEN: ""
1214
ECO_CI_CLONE_BRANCH: "main"
1315
ECO_CI_MACHINE_POWER_DATA: "gitlab_EPYC_7B12_saas-linux-small-amd64.sh"
1416
ECO_CI_API_ENDPOINT_ADD: "https://api.green-coding.io/v2/ci/measurement/add"
1517
ECO_CI_API_BADGE_GET: "https://api.green-coding.io/v1/ci/badge/get"
1618
ECO_CI_DASHBOARD_URL: "https://metrics.green-coding.io"
1719
ECO_CI_GMT_API_TOKEN: ""
18-
ECO_CI_ELECTRICITYMAPS_API_TOKEN: ""
1920

2021
.start_measurement:
2122
script:
@@ -26,7 +27,7 @@ variables:
2627
fi
2728
git clone --depth 1 --single-branch --branch "${ECO_CI_CLONE_BRANCH}" https://github.com/green-coding-solutions/eco-ci-energy-estimation /tmp/eco-ci-repo
2829
29-
/tmp/eco-ci-repo/scripts/setup.sh start_measurement "${ECO_CI_MACHINE_POWER_DATA}" "${CI_PIPELINE_ID}" "${CI_COMMIT_REF_NAME}" "${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}" "${CI_PROJECT_ID}" "gitlab-ci.yml" "${CI_COMMIT_SHA}" "gitlab" "${ECO_CI_SEND_DATA}" "${ECO_CI_FILTER_TYPE}" "${ECO_CI_FILTER_PROJECT}" "${ECO_CI_FILTER_MACHINE}" "${ECO_CI_FILTER_TAGS}" "${ECO_CI_CALCULATE_CO2}" "${ECO_CI_GMT_API_TOKEN}" "${ECO_CI_ELECTRICITYMAPS_API_TOKEN}" "${ECO_CI_JSON_OUTPUT}" "${ECO_CI_API_ENDPOINT_ADD}" "${ECO_CI_API_BADGE_GET}" "${ECO_CI_DASHBOARD_URL}"
30+
/tmp/eco-ci-repo/scripts/setup.sh start_measurement "${ECO_CI_MACHINE_POWER_DATA}" "${CI_PIPELINE_ID}" "${CI_COMMIT_REF_NAME}" "${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}" "${CI_PROJECT_ID}" "gitlab-ci.yml" "${CI_COMMIT_SHA}" "gitlab" "${ECO_CI_SEND_DATA}" "${ECO_CI_FILTER_TYPE}" "${ECO_CI_FILTER_PROJECT}" "${ECO_CI_FILTER_MACHINE}" "${ECO_CI_FILTER_TAGS}" "${ECO_CI_CO2_CALCULATION_METHOD}" "${ECO_CI_CO2_GRID_INTENSITY_CONSTANT}" "${ECO_CI_CO2_GRID_INTENSITY_API_TOKEN}" "${ECO_CI_GMT_API_TOKEN}" "${ECO_CI_JSON_OUTPUT}" "${ECO_CI_API_ENDPOINT_ADD}" "${ECO_CI_API_BADGE_GET}" "${ECO_CI_DASHBOARD_URL}"
3031
3132
.get_measurement:
3233
script:

0 commit comments

Comments
 (0)