{"id":37823224,"url":"https://github.com/armakuni/carbon-guard","last_synced_at":"2026-01-16T15:43:32.606Z","repository":{"id":178655368,"uuid":"661731700","full_name":"armakuni/carbon-guard","owner":"armakuni","description":"Skip the build if the carbon index is high","archived":false,"fork":false,"pushed_at":"2025-11-25T05:45:21.000Z","size":929,"stargazers_count":2,"open_issues_count":10,"forks_count":0,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-11-28T14:13:22.614Z","etag":null,"topics":["actions","carbon-emissions","net-zero"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/armakuni.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-07-03T14:14:58.000Z","updated_at":"2025-04-24T19:30:52.000Z","dependencies_parsed_at":"2025-12-08T00:03:22.517Z","dependency_job_id":null,"html_url":"https://github.com/armakuni/carbon-guard","commit_stats":{"total_commits":330,"total_committers":8,"mean_commits":41.25,"dds":"0.24545454545454548","last_synced_commit":"7c727a334b584608e20ff1560e6a4d1ede916af9"},"previous_names":["armakuni/carbon-guard"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/armakuni/carbon-guard","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/armakuni%2Fcarbon-guard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/armakuni%2Fcarbon-guard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/armakuni%2Fcarbon-guard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/armakuni%2Fcarbon-guard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/armakuni","download_url":"https://codeload.github.com/armakuni/carbon-guard/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/armakuni%2Fcarbon-guard/sbom","scorecard":{"id":207454,"data":{"date":"2025-08-11","repo":{"name":"github.com/armakuni/carbon-guard","commit":"dd9fcefe436263e57e5e45b2e01008ca2da148fc"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.3,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: jobLevel 'contents' permission set to 'write': .github/workflows/ci.yaml:59","Warn: no topLevel permission defined: .github/workflows/ci.yaml:1"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":8,"reason":"dependency not pinned by hash detected -- score normalized to 8","details":["Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yaml:110: update your workflow using https://app.stepsecurity.io/secureworkflow/armakuni/carbon-guard/ci.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yaml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/armakuni/carbon-guard/ci.yaml/main?enable=pin","Info:   4 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   7 out of   9 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Info: FSF or OSI recognized license: MIT License: LICENSE.md:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/ci.yaml:88"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 4 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T00:05:40.661Z","repository_id":178655368,"created_at":"2025-08-17T00:05:40.661Z","updated_at":"2025-08-17T00:05:40.661Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28479409,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actions","carbon-emissions","net-zero"],"created_at":"2026-01-16T15:43:32.522Z","updated_at":"2026-01-16T15:43:32.584Z","avatar_url":"https://github.com/armakuni.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Carbon Guard 👮\n\nCarbon Guard is a unique and environmentally conscious GitHub Action \u0026 CLI App\ndesigned to help reduce the carbon footprint of your CI/CD pipelines. It\nworks by monitoring real-time carbon intensity data and preventing\npipelines from running when the carbon intensity is high.\n\n## Usage\n\n\n```shell,script(name=\"usage\",expected_exit_code=0)\nuv run carbon_guard --help\n```\n\n``` ,verify(script_name=\"usage\",stream=stdout)\n                                                                                \n Usage: carbon_guard [OPTIONS] COMMAND [ARGS]...                                \n                                                                                \n╭─ Options ────────────────────────────────────────────────────────────────────╮\n│ --install-completion          Install completion for the current shell.      │\n│ --show-completion             Show completion for the current shell, to copy │\n│                               it or customize the installation.              │\n│ --help                        Show this message and exit.                    │\n╰──────────────────────────────────────────────────────────────────────────────╯\n╭─ Commands ───────────────────────────────────────────────────────────────────╮\n│ check      Check the current carbon intensity.                               │\n│ schedule   Find the lowest carbon time.                                      │\n╰──────────────────────────────────────────────────────────────────────────────╯\n\n```\n\n### Check\n\n```shell,script(name=\"usage-check\",expected_exit_code=0)\nuv run carbon_guard check --help\n```\n\n``` ,verify(script_name=\"usage-check\",stream=stdout)\n                                                                                \n Usage: carbon_guard check [OPTIONS]                                            \n                                                                                \n Check the current carbon intensity.                                            \n                                                                                \n╭─ Options ────────────────────────────────────────────────────────────────────╮\n│ *  --max-carbon-in…                       INTEGER           Set the max      │\n│                                                             carbon intensity │\n│                                                             in gCO2eq/kWh.   │\n│                                                             [env var:        │\n│                                                             MAX_CARBON_INTE… │\n│                                                             [default: None]  │\n│                                                             [required]       │\n│    --advise-only       --no-advise-on…                      Do not exit with │\n│                                                             an error if the  │\n│                                                             carbon intensity │\n│                                                             is above the max │\n│                                                             carbon           │\n│                                                             intensity.       │\n│                                                             [env var:        │\n│                                                             ADVISE_ONLY]     │\n│                                                             [default:        │\n│                                                             no-advise-only]  │\n│    --data-source                          [file|national-g  Where to read    │\n│                                           rid-eso-carbon-i  carbon intensity │\n│                                           ntensity|co2-sig  data from        │\n│                                           nal]              [env var:        │\n│                                                             DATA_SOURCE]     │\n│                                                             [default:        │\n│                                                             national-grid-e… │\n│    --from-file-car…                       PATH              File to read     │\n│                                                             carbon intensity │\n│                                                             from in file     │\n│                                                             mode             │\n│                                                             [env var:        │\n│                                                             FROM_FILE_CARBO… │\n│                                                             [default:        │\n│                                                             .carbon_intensi… │\n│    --national-grid…                       HTTP_OR_HTTPS_UR  URL for the      │\n│                                           L                 National Grid    │\n│                                                             ESO Carbon       │\n│                                                             Intensity API    │\n│                                                             [env var:        │\n│                                                             NATIONAL_GRID_E… │\n│                                                             [default:        │\n│                                                             https://api.car… │\n│    --co2-signal-ca…                       HTTP_OR_HTTPS_UR  URL for the CO2  │\n│                                           L                 Signal api       │\n│                                                             [env var:        │\n│                                                             CO2_SIGNAL_API_… │\n│                                                             [default:        │\n│                                                             https://api.co2… │\n│    --co2-signal-ap…                       TEXT              Api key for the  │\n│                                                             CO2 Signal api,  │\n│                                                             required in CO2  │\n│                                                             Signal mode      │\n│                                                             [env var:        │\n│                                                             CO2_SIGNAL_API_… │\n│                                                             [default: None]  │\n│    --co2-signal-co…                       TEXT              Country code to  │\n│                                                             get the carbon   │\n│                                                             intensity from   │\n│                                                             CO2 Signal api   │\n│                                                             [env var:        │\n│                                                             CO2_SIGNAL_COUN… │\n│                                                             [default: None]  │\n│    --help                                                   Show this        │\n│                                                             message and      │\n│                                                             exit.            │\n╰──────────────────────────────────────────────────────────────────────────────╯\n\n```\n\n### Schedule\n\n```shell,script(name=\"usage-schedule\",expected_exit_code=0)\nuv run carbon_guard schedule --help\n```\n\n``` ,verify(script_name=\"usage-schedule\",stream=stdout)\n                                                                                \n Usage: carbon_guard schedule [OPTIONS]                                         \n                                                                                \n Find the lowest carbon time.                                                   \n                                                                                \n╭─ Options ────────────────────────────────────────────────────────────────────╮\n│ *  --within                     HUMAN_READABLE_DURATI  Time period to        │\n│                                 ON                     predict the lowest    │\n│                                                        intensity within      │\n│                                                        [env var: WITHIN]     │\n│                                                        [default: None]       │\n│                                                        [required]            │\n│    --data-source                [file|national-grid-e  Where to read carbon  │\n│                                 so-carbon-intensity]   intensity data from   │\n│                                                        [env var:             │\n│                                                        DATA_SOURCE]          │\n│                                                        [default:             │\n│                                                        national-grid-eso-ca… │\n│    --from-file-carbon-i…        PATH                   File to read carbon   │\n│                                                        intensity from in     │\n│                                                        file mode             │\n│                                                        [env var:             │\n│                                                        FROM_FILE_CARBON_INT… │\n│                                                        [default:             │\n│                                                        .carbon_intensity]    │\n│    --national-grid-eso-…        HTTP_OR_HTTPS_URL      URL for the National  │\n│                                                        Grid ESO Carbon       │\n│                                                        Intensity API         │\n│                                                        [env var:             │\n│                                                        NATIONAL_GRID_ESO_CA… │\n│                                                        [default:             │\n│                                                        https://api.carbonin… │\n│    --help                                              Show this message and │\n│                                                        exit.                 │\n╰──────────────────────────────────────────────────────────────────────────────╯\n\n```\n\n### Common use case\n\nWhen comparing current carbon intensity levels to global carbon intensity\nbased on gCO2eq/kWh.\n\nComparing carbon levels with the expected outcome for high carbon intensity:\n\n```shell,script(name=\"carbon_threshold_exceeded\",  expected_exit_code=1)\ncarbon_intensity_is 1000\nuv run carbon_guard check --max-carbon-intensity=999\n```\n\n``` ,verify(script_name=\"carbon_threshold_exceeded\", stream=stdout)\nCarbon intensity is 1000 gCO2eq/kWh, which is above the max of 999 gCO2eq/kWh\n```\n\nYou may also return a successful exit code even on high carbon intensity by passing the `--advise-only` flag.\n\n```shell,script(name=\"carbon_threshold_exceeded_and_skipped\",  expected_exit_code=0)\ncarbon_intensity_is 1000\nuv run carbon_guard check --max-carbon-intensity=999 --advise-only\n```\n\nComparing carbon levels with the expected outcome for low carbon intensity:\n\n```shell,script(name=\"carbon_threshold_ok\",  expected_exit_code=0)\ncarbon_intensity_is 999\nuv run carbon_guard check --max-carbon-intensity=999\n```\n\n``` ,verify(script_name=\"carbon_threshold_ok\", stream=stdout)\nCarbon intensity is 999 gCO2eq/kWh, which is below or equal to the max of 999 gCO2eq/kWh\n```\n\n## Data Sources\n\n* [National Grid ESO Carbon Intensity](#national-grid-eso-carbon-intensity)\n* [CO2 Signal](#co2-signal)\n\nYou may change the data source by specifying the `--data-source` flag.\n\n## National Grid ESO Carbon Intensity\n\nUsing the [national-grid-eso-carbon-intensity data source](https://carbonintensity.org.uk/).\n[**note**] this only supplies data for the United Kingdom.\n\n```shell,script(name=\"national_grid_eso_carbon_threshold_ok\",  expected_exit_code=0)\nuv run carbon_guard check --data-source national-grid-eso-carbon-intensity --max-carbon-intensity=100000\n```\n\n``` ,skip()\nCarbon intensity is 98 gCO2eq/kWh, which is below or equal to the max of 100000 gCO2eq/kWh\n```\n\nYou can use this data provider to schedule find the forecasted lowest carbon intensity within a given time period.\n\n```shell,script(name=\"national_grid_eso_carbon_threshold_ok\",  expected_exit_code=0)\nuv run carbon_guard schedule --data-source national-grid-eso-carbon-intensity --within \"1 hour\"\n```\n\n``` ,skip()\n2023-07-07T09:30:00+00:00\n```\n\n### CO2 Signal\n\nUsing the [co2-signal data source](https://www.co2signal.com/)\n[**note**] This data source requires an account (free/paid) which will supply an API key for usage, and does not support forecasting.\n\n```shell,script(name=\"co2-signal-carbon-threshold-ok\",  expected_exit_code=0)\n# export CO2_SIGNAL_API_KEY=\u003cyour_api_key_here\u003e\nuv run carbon_guard check --data-source co2-signal --max-carbon-intensity=100000 --co2-signal-country-code=GB\n```\n\n``` ,skip()\nCarbon intensity is 107 gCO2eq/kWh, which is below or equal to the max of 100000 gCO2eq/kWh\n```\n\n#### Errors\n\nif you don't provide a `co2-signal-country-code` the call will fail.\n\n```shell,script(name=\"co2-signal-no-country-code-error\",  expected_exit_code=1)\n# export CO2_SIGNAL_API_KEY=\u003cyour_api_key_here\u003e\nuv run carbon_guard check --data-source co2-signal --max-carbon-intensity=100000\n```\n\n``` ,verify(script_name=\"co2-signal-no-country-code-error\", stream=stdout)\nNo country code provided to CO2 Signal Api.\n```\n\nif you don't provide a `co2-signal-api-key` the call will fail.\n\n```shell,script(name=\"co2-signal-no-api-key-error\",  expected_exit_code=1)\nexport CO2_SIGNAL_API_KEY=\"\"\nuv run carbon_guard check --data-source co2-signal --max-carbon-intensity=100000 --co2-signal-country-code=GB\n```\n\n``` ,verify(script_name=\"co2-signal-no-api-key-error\", stream=stdout)\nNo API key found for CO2 Signal API.\n```\n\n## Adding to your pipelines\n\nThis tool is intended to be run inside a pipeline to either fail or skip steps within, based on the current carbon\nintensity levels.\n\n### Using GitHub Actions\n\nIf you intend to fail the build based on the carbon intensity level\n\n```yaml,skip()\n  validate-action:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: armakuni/carbon-guard@v0.4.1\n        with:\n          max_carbon_intensity: 500\n      - run: echo Some complicated compute task\n```\n\nAlternatively if you want to simply skip a step if the carbon intensity is too high you can use the `continue-on-error`\nflag.\n\n```yaml,skip()\n  validate-action:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: armakuni/carbon-guard@v0.4.1\n        continue-on-error: true\n        id: carbon_guard\n        with:\n          max_carbon_intensity: 500\n      - run: echo Some complicated compute task\n        if: steps.carbon_guard.outcome == 'success'\n```\n\n### Other pipelines\n\nYou can run in other pipelines as a command line tool\n\n```shell, skip()\npip install carbon-guard\ncarbon_guard --help\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farmakuni%2Fcarbon-guard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farmakuni%2Fcarbon-guard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farmakuni%2Fcarbon-guard/lists"}