ci-info 0.3.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,22 @@
1
+ version: 2.1
2
+
3
+ jobs:
4
+ test:
5
+ docker:
6
+ - image: cimg/python:3.14
7
+ steps:
8
+ - checkout
9
+ - run:
10
+ name: Install ci-info (+ pytest)
11
+ command: |
12
+ uv sync --all-extras --dev
13
+ - run:
14
+ name: Run test
15
+ command: |
16
+ uv run pytest tests/
17
+
18
+ workflows:
19
+ version: 2
20
+ test:
21
+ jobs:
22
+ - test
@@ -0,0 +1,9 @@
1
+ # Set update schedule for GitHub Actions
2
+ version: 2
3
+ updates:
4
+
5
+ - package-ecosystem: "github-actions"
6
+ directory: "/"
7
+ schedule:
8
+ # Check for updates to GitHub Actions every week
9
+ interval: "weekly"
@@ -0,0 +1,84 @@
1
+ name: Build Test and Publish
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ tags:
8
+ - '*'
9
+ pull_request:
10
+ branches:
11
+ - master
12
+ workflow_dispatch:
13
+
14
+
15
+ defaults:
16
+ run:
17
+ shell: bash
18
+
19
+ concurrency:
20
+ group: ${{ github.workflow }}-${{ github.ref }}
21
+ cancel-in-progress: true
22
+
23
+ permissions:
24
+ contents: read
25
+
26
+ jobs:
27
+ build:
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - uses: actions/checkout@v6
31
+ with:
32
+ fetch-depth: 0
33
+ - name: Install the latest version of uv
34
+ uses: astral-sh/setup-uv@v7
35
+ with:
36
+ python-version: 3
37
+ - name: Build
38
+ run: uv build
39
+ - name: Upload sdist and wheel artifacts
40
+ uses: actions/upload-artifact@v6
41
+ with:
42
+ name: dist
43
+ path: dist/
44
+
45
+ test:
46
+ runs-on: ubuntu-latest
47
+ strategy:
48
+ matrix:
49
+ python:
50
+ - "3.10"
51
+ - "3.11"
52
+ - "3.12"
53
+ - "3.13"
54
+ - "3.14"
55
+ - "3.15"
56
+ steps:
57
+ - uses: actions/checkout@v6
58
+ - name: Install the latest version of uv
59
+ uses: astral-sh/setup-uv@v7
60
+ with:
61
+ python-version: ${{ matrix.python }}
62
+ - name: Install ci-info
63
+ run: uv sync --all-extras --dev
64
+ - name: Test ci-info
65
+ run: uv run pytest tests/
66
+
67
+ publish:
68
+ needs: [ build, test ]
69
+ runs-on: ubuntu-latest
70
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
71
+ environment:
72
+ name: pypi
73
+ url: https://pypi.org/p/ci-info/
74
+ permissions:
75
+ id-token: write
76
+ contents: read
77
+ steps:
78
+ - uses: actions/checkout@v6
79
+ - uses: actions/download-artifact@v7
80
+ with:
81
+ name: dist
82
+ path: dist/
83
+ - name: Distribute to PyPI
84
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,8 @@
1
+ *.pyc
2
+ .vscode/
3
+ .pytest_cache/
4
+ *egg-info
5
+ __pycache__
6
+ .venv
7
+ .ruff_cache
8
+ uv.lock
@@ -0,0 +1,13 @@
1
+ # vim ft=yaml
2
+ language: python
3
+ python:
4
+ - 3.5
5
+ - 3.6
6
+ - 3.7
7
+ - 3.8
8
+
9
+ install:
10
+ - pip install -e .[test]
11
+
12
+ script:
13
+ - pytest -v --doctest-modules ci_info/tests/test_travis.py
@@ -0,0 +1,29 @@
1
+ 0.4.0 (February 2, 2026)
2
+ ========================
3
+ - Enable is_pr detection for AWS CodeBuild, Appcircle, and Vercel
4
+ - Add new CI providers:
5
+ Agola CI, Cloudflare Pages, Cloudflare Workers, Earthly CI,
6
+ Gerrit CI, Gitea Actions, Google Cloud Build, Harness CI,
7
+ Heroku, Prow, ReleaseHub, Sourcehut, Vela, and Woodpecker
8
+
9
+ 0.3.0 (July 27, 2022)
10
+ =====================
11
+ Adds CI detection for:
12
+
13
+ -Appcircle
14
+ -Codefresh
15
+ -Expo Application Services
16
+ -Github Actions
17
+ -LayerCI
18
+ -Render
19
+ -Screwdriver
20
+ -Vercel
21
+ -Visual Studio App Center
22
+
23
+ Additionally, drops support for Python 3.5 and 3.6, as they are now EOL.
24
+
25
+ 0.2.0 (April 16, 2020)
26
+ ======================
27
+
28
+ - Renamed package import to `ci_info`
29
+ - Added tests for Circle CI.
@@ -1,25 +1,22 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: ci-info
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Continuous Integration Information
5
- Home-page: https://github.com/mgxd/ci-info
6
- Author: Mathias Goncalves
7
- Author-email: mathiasg@mit.edu
5
+ Project-URL: Homepage, https://github.com/mgxd/ci-info
6
+ Author-email: Mathias Goncalves <mathiasg@stanford.edu>
8
7
  License: MIT
9
- Classifier: Development Status :: 3 - Alpha
8
+ License-File: LICENSE
9
+ Classifier: Development Status :: 5 - Production/Stable
10
10
  Classifier: Intended Audience :: Developers
11
- Classifier: License :: OSI Approved :: Apache Software License
12
- Classifier: Programming Language :: Python :: 3.7
13
- Classifier: Programming Language :: Python :: 3.8
14
- Classifier: Programming Language :: Python :: 3.9
15
- Classifier: Programming Language :: Python :: 3.10
16
- Provides: ci_info
17
- Requires-Python: >=3.7
18
- Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Provides-Extra: all
14
+ Requires-Dist: pytest; extra == 'all'
19
15
  Provides-Extra: test
16
+ Requires-Dist: pytest; extra == 'test'
20
17
  Provides-Extra: tests
21
- Provides-Extra: all
22
- License-File: LICENSE
18
+ Requires-Dist: pytest; extra == 'tests'
19
+ Description-Content-Type: text/markdown
23
20
 
24
21
  # ci-info
25
22
 
@@ -39,10 +36,11 @@ Officially supported CI servers:
39
36
 
40
37
  | Name | isPR |
41
38
  | ------------------------------------------------------------------------------- | ---- |
42
- | [AWS CodeBuild](https://aws.amazon.com/codebuild/) | 🚫 |
39
+ | [Agola CI](https://agola.io/) | |
40
+ | [Appcircle](https://appcircle.io/) | ✅ |
43
41
  | [AppVeyor](http://www.appveyor.com) | ✅ |
42
+ | [AWS CodeBuild](https://aws.amazon.com/codebuild/) | ✅ |
44
43
  | [Azure Pipelines](https://azure.microsoft.com/en-us/services/devops/pipelines/) | ✅ |
45
- | [Appcircle](https://appcircle.io/) | 🚫 |
46
44
  | [Bamboo](https://www.atlassian.com/software/bamboo) by Atlassian | 🚫 |
47
45
  | [Bitbucket Pipelines](https://bitbucket.org/product/features/pipelines) | ✅ |
48
46
  | [Bitrise](https://www.bitrise.io/) | ✅ |
@@ -50,32 +48,45 @@ Officially supported CI servers:
50
48
  | [Buildkite](https://buildkite.com) | ✅ |
51
49
  | [CircleCI](http://circleci.com) | ✅ |
52
50
  | [Cirrus CI](https://cirrus-ci.org) | ✅ |
51
+ | [Cloudflare Pages](https://pages.cloudflare.com/) | 🚫 |
52
+ | [Cloudflare Workers](https://pages.cloudflare.com/) | 🚫 |
53
53
  | [Codefresh](https://codefresh.io/) | ✅ |
54
54
  | [Codeship](https://codeship.com) | 🚫 |
55
55
  | [Drone](https://drone.io) | ✅ |
56
56
  | [dsari](https://github.com/rfinnie/dsari) | 🚫 |
57
+ | [Earthly CI](https://earthly.dev/) | 🚫 |
57
58
  | [Expo Application Services](https://expo.dev/eas) | 🚫 |
59
+ | [Gerrit CI](https://www.gerritcodereview.com) | 🚫 |
58
60
  | [GitHub Actions](https://github.com/features/actions/) | ✅ |
59
61
  | [GitLab CI](https://about.gitlab.com/gitlab-ci/) | ✅ |
62
+ | [Gitea Actions](https://about.gitea.com/) | 🚫 |
60
63
  | [GoCD](https://www.go.cd/) | 🚫 |
64
+ | [Google Cloud Build](https://cloud.google.com/build) | 🚫 |
65
+ | [Harness CI](https://www.harness.io/products/continuous-integration) | 🚫 |
66
+ | [Heroku](https://www.heroku.com) | 🚫 |
61
67
  | [Hudson](http://hudson-ci.org) | 🚫 |
62
68
  | [Jenkins CI](https://jenkins-ci.org) | ✅ |
63
69
  | [LayerCI](https://layerci.com/) | ✅ |
64
70
  | [Magnum CI](https://magnum-ci.com) | 🚫 |
65
71
  | [Netlify CI](https://www.netlify.com/) | ✅ |
66
72
  | [Nevercode](http://nevercode.io/) | ✅ |
73
+ | [Prow](https://docs.prow.k8s.io/) | 🚫 |
74
+ | [ReleaseHub](https://releasehub.com/) | 🚫 |
67
75
  | [Render](https://render.com/) | ✅ |
68
76
  | [Sail CI](https://sail.ci/) | ✅ |
69
77
  | [Screwdriver](https://screwdriver.cd/) | ✅ |
70
78
  | [Semaphore](https://semaphoreci.com) | ✅ |
71
79
  | [Shippable](https://www.shippable.com/) | ✅ |
72
80
  | [Solano CI](https://www.solanolabs.com/) | ✅ |
81
+ | [Sourcehut](https://sourcehut.org/) | 🚫 |
73
82
  | [Strider CD](https://strider-cd.github.io/) | 🚫 |
74
83
  | [TaskCluster](http://docs.taskcluster.net) | 🚫 |
75
84
  | [TeamCity](https://www.jetbrains.com/teamcity/) by JetBrains | 🚫 |
76
85
  | [Travis CI](http://travis-ci.org) | ✅ |
77
- | [Vercel](https://vercel.com/) | 🚫 |
86
+ | [Vela](https://go-vela.github.io/docs/) | |
87
+ | [Vercel](https://vercel.com/) | ✅ |
78
88
  | [Visual Studio App Center](https://appcenter.ms/) | 🚫 |
89
+ | [Woodpecker](https://woodpecker-ci.org/) | ✅ |
79
90
 
80
91
 
81
92
  ## Installation
@@ -16,10 +16,11 @@ Officially supported CI servers:
16
16
 
17
17
  | Name | isPR |
18
18
  | ------------------------------------------------------------------------------- | ---- |
19
- | [AWS CodeBuild](https://aws.amazon.com/codebuild/) | 🚫 |
19
+ | [Agola CI](https://agola.io/) | |
20
+ | [Appcircle](https://appcircle.io/) | ✅ |
20
21
  | [AppVeyor](http://www.appveyor.com) | ✅ |
22
+ | [AWS CodeBuild](https://aws.amazon.com/codebuild/) | ✅ |
21
23
  | [Azure Pipelines](https://azure.microsoft.com/en-us/services/devops/pipelines/) | ✅ |
22
- | [Appcircle](https://appcircle.io/) | 🚫 |
23
24
  | [Bamboo](https://www.atlassian.com/software/bamboo) by Atlassian | 🚫 |
24
25
  | [Bitbucket Pipelines](https://bitbucket.org/product/features/pipelines) | ✅ |
25
26
  | [Bitrise](https://www.bitrise.io/) | ✅ |
@@ -27,32 +28,45 @@ Officially supported CI servers:
27
28
  | [Buildkite](https://buildkite.com) | ✅ |
28
29
  | [CircleCI](http://circleci.com) | ✅ |
29
30
  | [Cirrus CI](https://cirrus-ci.org) | ✅ |
31
+ | [Cloudflare Pages](https://pages.cloudflare.com/) | 🚫 |
32
+ | [Cloudflare Workers](https://pages.cloudflare.com/) | 🚫 |
30
33
  | [Codefresh](https://codefresh.io/) | ✅ |
31
34
  | [Codeship](https://codeship.com) | 🚫 |
32
35
  | [Drone](https://drone.io) | ✅ |
33
36
  | [dsari](https://github.com/rfinnie/dsari) | 🚫 |
37
+ | [Earthly CI](https://earthly.dev/) | 🚫 |
34
38
  | [Expo Application Services](https://expo.dev/eas) | 🚫 |
39
+ | [Gerrit CI](https://www.gerritcodereview.com) | 🚫 |
35
40
  | [GitHub Actions](https://github.com/features/actions/) | ✅ |
36
41
  | [GitLab CI](https://about.gitlab.com/gitlab-ci/) | ✅ |
42
+ | [Gitea Actions](https://about.gitea.com/) | 🚫 |
37
43
  | [GoCD](https://www.go.cd/) | 🚫 |
44
+ | [Google Cloud Build](https://cloud.google.com/build) | 🚫 |
45
+ | [Harness CI](https://www.harness.io/products/continuous-integration) | 🚫 |
46
+ | [Heroku](https://www.heroku.com) | 🚫 |
38
47
  | [Hudson](http://hudson-ci.org) | 🚫 |
39
48
  | [Jenkins CI](https://jenkins-ci.org) | ✅ |
40
49
  | [LayerCI](https://layerci.com/) | ✅ |
41
50
  | [Magnum CI](https://magnum-ci.com) | 🚫 |
42
51
  | [Netlify CI](https://www.netlify.com/) | ✅ |
43
52
  | [Nevercode](http://nevercode.io/) | ✅ |
53
+ | [Prow](https://docs.prow.k8s.io/) | 🚫 |
54
+ | [ReleaseHub](https://releasehub.com/) | 🚫 |
44
55
  | [Render](https://render.com/) | ✅ |
45
56
  | [Sail CI](https://sail.ci/) | ✅ |
46
57
  | [Screwdriver](https://screwdriver.cd/) | ✅ |
47
58
  | [Semaphore](https://semaphoreci.com) | ✅ |
48
59
  | [Shippable](https://www.shippable.com/) | ✅ |
49
60
  | [Solano CI](https://www.solanolabs.com/) | ✅ |
61
+ | [Sourcehut](https://sourcehut.org/) | 🚫 |
50
62
  | [Strider CD](https://strider-cd.github.io/) | 🚫 |
51
63
  | [TaskCluster](http://docs.taskcluster.net) | 🚫 |
52
64
  | [TeamCity](https://www.jetbrains.com/teamcity/) by JetBrains | 🚫 |
53
65
  | [Travis CI](http://travis-ci.org) | ✅ |
54
- | [Vercel](https://vercel.com/) | 🚫 |
66
+ | [Vela](https://go-vela.github.io/docs/) | |
67
+ | [Vercel](https://vercel.com/) | ✅ |
55
68
  | [Visual Studio App Center](https://appcenter.ms/) | 🚫 |
69
+ | [Woodpecker](https://woodpecker-ci.org/) | ✅ |
56
70
 
57
71
 
58
72
  ## Installation
@@ -0,0 +1,102 @@
1
+ from builtins import str # remove this once Py2 is dropped
2
+ import json
3
+ import os
4
+
5
+ try:
6
+ from ._version import __version__
7
+ except ImportError:
8
+ __version__ = "0+unknown"
9
+
10
+ _here = os.path.dirname(__file__)
11
+ with open(os.path.join(_here, "vendors.json")) as fp:
12
+ vendors = json.load(fp)
13
+
14
+
15
+ def _detect_env(env=None):
16
+ if env is None:
17
+ env = os.environ
18
+
19
+ for vendor in vendors:
20
+ vend = vendor.get("env")
21
+ if isinstance(vend, str) and vend in env:
22
+ return vendor
23
+ if isinstance(vend, list):
24
+ if all(ev in env for ev in vend):
25
+ return vendor
26
+ elif isinstance(vend, dict):
27
+ if "includes" in vend:
28
+ # Envvar needs to be present and include some value
29
+ if vend["env"] in env and vend["includes"] in env[vend["env"]]:
30
+ return vendor
31
+ elif "any" in vend:
32
+ if any(ev in env for ev in vend["any"]):
33
+ return vendor
34
+ else:
35
+ for ev, val in vend.items():
36
+ if ev in env and env[ev] == val:
37
+ return vendor
38
+ return {}
39
+
40
+
41
+ def name(env=None):
42
+ """
43
+ Returns a string containing name of the CI server the code is running on.
44
+ If CI server is not detected, returns None.
45
+ """
46
+ return _detect_env(env).get("name")
47
+
48
+
49
+ def is_ci(env=None):
50
+ """
51
+ Returns a boolean. Will be `True` if the code is running on a CI server,
52
+ otherwise `False`.
53
+ """
54
+ return bool(name(env))
55
+
56
+
57
+ def is_pr(env=None):
58
+ """
59
+ Returns a boolean if PR detection is supported for the current CI server.
60
+ Will be `True` if a PR is being tested, otherwise `False`. If PR detection
61
+ is not supported for the current CI server, the value will be `None`.
62
+ """
63
+ if env is None:
64
+ env = os.environ
65
+ vendor = _detect_env(env)
66
+
67
+ vpr = vendor.get("pr")
68
+ if vpr is None:
69
+ return
70
+
71
+ if isinstance(vpr, str):
72
+ return bool(env.get(vpr))
73
+ if isinstance(vpr, dict):
74
+ if "env" in vpr:
75
+ # Envvar is not equal to
76
+ if "ne" in vpr:
77
+ return bool(env.get(vpr["env"])) and env.get(vpr["env"]) != vpr["ne"]
78
+ # Envvar is one of a set of values
79
+ elif "any" in vpr:
80
+ return env.get(vpr["env"]) in vpr["any"]
81
+ # Envvar is one of a set of values
82
+ elif "any" in vpr:
83
+ for k in vpr["any"]:
84
+ if env.get(k):
85
+ return True
86
+ return False
87
+ # Specific value(s)
88
+ else:
89
+ for k, v in vpr.items():
90
+ if env.get(k) != v:
91
+ return False
92
+ return True
93
+ return None
94
+
95
+
96
+ def info(env=None):
97
+ """Return a dictionary with all info: name, is_ci, is_pr."""
98
+ return {
99
+ "name": name(env),
100
+ "is_ci": is_ci(env),
101
+ "is_pr": is_pr(env),
102
+ }