-
Notifications
You must be signed in to change notification settings - Fork 17
/
action.yml
183 lines (168 loc) · 8.94 KB
/
action.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
name: 'Eco CI Energy Estimation'
description: 'Estimate the energy of Linux Github Actions Runner VMs via ML Model'
branding:
icon: "battery-charging"
color: "green"
inputs:
task:
description: 'Task to be executed (start-measurement, get-measurement, display-results)'
required: true
branch:
description: 'Used to correctly identify this CI run for the Badge. Uses github.ref_name by default'
default: ${{ github.ref_name }}
required: false
label:
description: 'Label for the get-measurement task, to mark what this measurement correlates to in your workflow'
default: null
required: false
machine-power-data:
description: 'The file to read the machine power data from. Default will be 4 core AMD EPYC 7763 Github Runner'
default: "github_EPYC_7763_4_CPU_shared.sh"
required: false
send-data:
description: '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.'
default: true
required: false
calculate-co2:
description: 'Uses the grid carbon intensity of the run location to estimate the emitted carbon for the measurements.'
default: true
required: false
display-table:
description: 'Show the energy reading results in a table during display-results step'
default: true
required: false
display-badge:
description: 'Shows the badge for the ci run during display-results step'
default: true
required: false
pr-comment:
description: 'Add a comment to the PR with the results during display-results step'
default: false
required: false
json-output:
description: 'Output measurement data also as JSON artifacts'
default: false
required: false
gh-api-base:
description: 'Base URL of the Github API to send data to (including schema). Default is "github.api_url" (which resolves to https://api.github.com in free and many enterprise setups), but can be changed to your hostname if you have a custom hosted Github Enterprise'
default: ${{ github.api_url }}
required: false
type:
description: 'If you want filter data in the GMT Dashboard or in CarbonDB you can here manually set a type for drill-down later. Defaults to "machine.ci"'
default: 'machine.ci'
required: false
project:
description: 'If you want filter data in the GMT Dashboard or in CarbonDB you can here manually set a project for drill-down later. Defaults to "CI/CD"'
default: 'CI/CD'
required: false
machine:
description: 'If you want filter data in the GMT Dashboard or in CarbonDB you can here manually set a machine for drill-down later. Defaults to ubuntu-latest'
default: 'ubuntu-latest'
required: false
tags:
description: 'If you want filter data in the GMT Dashboard or in CarbonDB you can here manually set tags for drill-down later. Please supply comma separated. Tags cannot have commas itself or contain quotes. Defaults to empty'
default: ''
required: false
gmt-api-token:
description: 'If you are not using the default user for the GMT API supply your auth token. We recommend to have this as a GitHub Secret'
default: ''
required: false
api-endpoint-add:
description: '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"'
default: 'https://api.green-coding.io/v2/ci/measurement/add'
required: false
api-endpoint-badge-get:
description: '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'
default: 'https://api.green-coding.io/v1/ci/badge/get'
required: false
electricitymaps-api-token:
description: 'API token for electricitymaps in case you get rate-limited. See documentation for details'
default: ''
required: false
outputs:
data-total-json:
description: "Contains the data of the total measurement which is retrieved by the 'display-results' task."
value: ${{ steps.run-total-model.outputs.data-total-json }}
data-lap-json:
description: "Contains the data of the most recent measurement which is retrieved by the 'get-measurement' task."
value: ${{ steps.run-lap-model.outputs.data-lap-json }}
runs:
using: 'composite'
steps:
- id: guard
if: inputs.task != 'start-measurement' && inputs.task != 'get-measurement' && inputs.task != 'display-results'
shell: bash
run: |
echo 'Please call the Eco-CI Energy Estimation with a valid task name: start-measurement, get-measurement, or display-results' >> $GITHUB_STEP_SUMMARY
echo "Eco-CI task was called with ${{inputs.task}} instead" >> $GITHUB_STEP_SUMMARY
fail('Invalid task name specified')
- id: start-measurement
if: inputs.task == 'start-measurement'
name: Starting measurement
shell: bash
run: |
workflow_id="${{github.workflow}}"
workflow_name="${{github.workflow}}"
if ${{inputs.send-data}}; then
workflow_id=$(curl -s -H "Authorization: Bearer ${{github.token}}" ${{ inputs.gh-api-base }}/repos/${{ github.repository }}/actions/runs/${{ github.run_id }} | jq -r .workflow_id)
fi
workflow_id=${workflow_id:-"not_set"}
workflow_name=${workflow_name:-"not_set"}
${{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 }}"
- if: inputs.task == 'get-measurement'
id: run-lap-model
name: Running estimation model
env:
NAME: ${{ github.workflow }}
shell: bash
run: |
label='${{ contains(inputs.label, '"') && 'No quotes allowed in labels' || inputs.label }}'
label_cleaned=$(echo "$label" | tr -d "$&;\'")
echo "Cleaned label: $label_cleaned"
"${{ github.action_path }}/scripts/make_measurement.sh" make_measurement "$label_cleaned"
data_file="/tmp/test.bash"
lap_data_file="/tmp/eco-ci/lap-data.json"
if [[ -e $lap_data_file ]]; then
echo "data-lap-json=$(cat $lap_data_file)" >> $GITHUB_OUTPUT
fi
- if: inputs.task == 'display-results'
name: get estimation for total energy
id: run-total-model
shell: bash
run: |
${{github.action_path}}/scripts/display_results.sh display_results "${{inputs.display-table}}" "${{inputs.display-badge}}"
cat "/tmp/eco-ci/output.txt" >> $GITHUB_STEP_SUMMARY
total_data_file="/tmp/eco-ci/total-data.json"
if [[ -e $total_data_file ]]; then
echo "data-total-json=$(cat $total_data_file)" >> $GITHUB_OUTPUT
fi
echo "Checking if PR comment is needed"
echo "inputs.pr-comment: ${{ inputs.pr-comment }}"
echo "github.event_name: ${{ github.event_name }}"
- if: inputs.task == 'display-results' && inputs.pr-comment == 'true' && github.event_name == 'pull_request'
name: Minimize Old Comment and Post New Comment
id: pr-comment
shell: bash
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
echo 'Running PR-Comment task'
COMMENTS=$(curl -s -H "Authorization: Bearer ${{github.token}}" "${{ inputs.gh-api-base }}/repos/${{ github.repository }}/issues/$PR_NUMBER/comments")
echo "$COMMENTS" | jq -c --arg username "github-actions[bot]" '.[] | select(.user.login == $username and (.body | index("Eco-CI") // false))' | while read -r comment; do
COMMENT_ID=$(echo "$comment" | jq -r '.id')
COMMENT_BODY=$(echo "$comment" | jq -r '.body')
INNER_BODY=$(echo "$COMMENT_BODY" | sed 's/<details><summary>Old Energy Estimation<\/summary>//g' | sed 's/<\/details>//g')
## indentation here is important, otherwise newlines are not properly sent/processed
PAYLOAD=$(jq --null-input --arg body "<details><summary>Old Energy Estimation</summary>
$INNER_BODY
</details>" '{"body": $body}')
curl -s -H "Authorization: Bearer ${{github.token}}" -X PATCH -d "$PAYLOAD" "${{ inputs.gh-api-base }}/repos/${{ github.repository }}/issues/comments/$COMMENT_ID"
echo "Comment $COMMENT_ID collapsed."
done
NEW_COMMENT=$(cat "/tmp/eco-ci/output-pr.txt" | jq -Rs '.')
API_URL="${{ inputs.gh-api-base }}/repos/${{ github.repository }}/issues/${PR_NUMBER}/comments"
curl -X POST -H "Authorization: Bearer ${{github.token}}" -d @- $API_URL <<EOF
{
"body": $NEW_COMMENT
}
EOF