{"id":13936328,"url":"https://github.com/getsentry/zeus","last_synced_at":"2025-07-19T21:32:24.728Z","repository":{"id":22397351,"uuid":"96131433","full_name":"getsentry/zeus","owner":"getsentry","description":"WIP: A dashboard for CI","archived":true,"fork":false,"pushed_at":"2024-05-06T15:39:41.000Z","size":7347,"stargazers_count":205,"open_issues_count":64,"forks_count":20,"subscribers_count":60,"default_branch":"master","last_synced_at":"2025-07-10T06:21:56.338Z","etag":null,"topics":["continuous-integration","python","python3","react","tag-archived"],"latest_commit_sha":null,"homepage":"https://zeus.ci","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/getsentry.png","metadata":{"funding":{"custom":["https://sentry.io/pricing/","https://sentry.io/"]},"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2017-07-03T16:39:35.000Z","updated_at":"2024-11-28T16:33:26.000Z","dependencies_parsed_at":"2024-05-06T16:44:38.949Z","dependency_job_id":null,"html_url":"https://github.com/getsentry/zeus","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/getsentry/zeus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getsentry%2Fzeus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getsentry%2Fzeus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getsentry%2Fzeus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getsentry%2Fzeus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/getsentry","download_url":"https://codeload.github.com/getsentry/zeus/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getsentry%2Fzeus/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266019657,"owners_count":23864916,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["continuous-integration","python","python3","react","tag-archived"],"created_at":"2024-08-07T23:02:34.353Z","updated_at":"2025-07-19T21:32:19.718Z","avatar_url":"https://github.com/getsentry.png","language":"Python","readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://user-images.githubusercontent.com/1433023/32629198-3c6f225e-c54d-11e7-96db-99fd22709a1b.png\" width=\"271\"\u003e\n\u003c/p\u003e\n\n# Zeus\n\n**This project is under development.**\n\nZeus is a frontend and analytics provider for CI solutions. It is inspired by the work done at Dropbox on [Changes](https://github.com/dropbox/changes/).\n\n## User Guide\n\nCurrently Zeus publicly supports GitHub.com as well as easy integration with Travis CI.\n\nTo add a new project:\n\n1. Add a repository (via settings).\n2. Go to the repository's settings and generate a new Hook.\n3. Bind ZEUS_HOOK_BASE as a secret environment variable in Travis.\n4. Update your .travis.yml to include the Zeus webhook.\n5. (Optional) Update your .travis.yml to include artifact upload.\n6. (Optional, not yet recommended) Update your .travis.yml to disable Travis' native email notifications.\n\nOnce you've added a project Zeus will automatically update with details from any builds you've run.\n\nSome quick caveats:\n\n- The project is still pretty early on, and may break/change without warning.\n- travis-ci.com and GitHub Enterprise are not yet supported.\n- Notifications will only be triggered for users which have authenticated against Zeus.\n\nIf you want to use Zeus with a build system that's not currently supported, see the details on \"Hooks\" in the documentation.\n\n### Supported Artifact Types\n\nWhile you can upload any kind of Artifact to zeus (e.g. `.html` output), the platform has knowledge of certain types\nand will grant additional functionality if they're present.\n\nThe recommended way to support artifacts is to configure a post-build step (on both failure and success) to do something similar to the following:\n\n```bash\nnpm install -g @zeus-ci/cli\n$(npm bin -g)/zeus upload -t \"application/x-junit+xml\" jest.junit.xml\n$(npm bin -g)/zeus upload -t \"application/x-cobertura+xml\" coverage.xml\n```\n\n#### Code Coverage\n\n- application/x-clover+xml\n- application/x-cobertura+xml\n\n#### xUnit\n\n- application/x-bitten+xml\n- application/x-junit+xml\n- application/x-xunit+xml\n\n#### Style Checks\n\n- application/x-checkstyle+xml\n- text/x-pep8\n- text/x-pycodestyle\n- test/x-pylint\n\n#### Webpack Stats\n\nWebpack stats can be generated with:\n\n```bash\nwebpack --profile --json \u003e webpack-stats.json\n```\n\nThey should be submitted with the `application/x-webpack-stats+json` type.\n\n## Contributing\n\n### Requirements\n\n- Python 3.8\n- Node (and [Volta](https://volta.sh/))\n- Postgres 9.4+\n\nNote: If you're using pyenv for Python and macOS Mojave and having issues installing 3.7.1, take a look here:\n\nhttps://github.com/pyenv/pyenv/issues/1219\n\n### Setup\n\n```shell\n# install poetry\ncurl -sSL https://raw.githubusercontent.com/sdispater/poetry/0.12.10/get-poetry.py | python\n\n# load dependencies\nmake\n\n# initialize config\npoetry run zeus init\n```\n\nNote, before running any future Python commands (including `zeus`), you'll\nneed to activate the environment:\n\n```shell\npoetry shell\n```\n\nYou can also setup [direnv](https://direnv.net/) to automatically activate the environment.\n\nOnce dependencies are resolved, bootstrap the database (see `Makefile` for details):\n\n```shell\nmake db\n```\n\nFinally, launch the webserver:\n\n```shell\nzeus devserver\n\n# or alternatively, with workers:\nzeus devserver --workers\n```\n\n### Getting some data\n\n```shell\n$ zeus repos add https://github.com/getsentry/zeus.git\n```\n\nOnce you've authenticated, give yourself access to the repository:\n\n```shell\n$ zeus repos access add https://github.com/getsentry/zeus.git [you@example.com]\n```\n\nAdditionally, you can generate some mock data:\n\n```shell\n$ zeus mocks load-all\n```\n\n### Layout\n\n```\nzeus\n├── setup.py                // server dependencies\n├── zeus                    // server code\n|   ├── artifacts           // artifact handlers\n|   ├── api\n|   |   ├── resources       // api endpoints/resources\n|   |   └── schemas         // api serializer/schemas\n|   ├── cli                 // command line utilities\n|   ├── models              // database schema\n|   ├── storage             // file storage implementations\n|   ├── tasks               // async task definitions\n|   ├── vcs                 // version control system implementations\n|   └── web                 // server-rendered web views\n├── templates               // server-rendered templates\n├── public                  // general static assets\n├── package.json            // web client dependencies\n└── webapp                  // web client\n    ├── actions             // redux actions\n    ├── components          // react components\n    ├── reducers            // redux reducers\n    ├── routes.js           // routes (react-router)\n    └── pages.js            // react components (pages)\n```\n\n### Data Model\n\n- Most models contain a GUID (UUID) primary key.\n- Some generalized models (such as `ItemStat`) are keyed by GUID, and do not contain backrefs or constraints.\n- Access is controlled at the repository level, and is generally enforced if you use the `{ModelClass}.query` utilities.\n- Refs are unresolved (pointers to shas). They are often resolved asynchronously. Models containing a sha will also often contain a parallel ref field.\n\n```\nzeus\n├── ApiToken\n|   └── ApiTokenRepositoryAccess\n├── Hook\n├── Repository\n|   ├── RepositoryAccess\n|   ├── ItemOption\n|   ├── Build\n|   |   ├── ItemStat\n|   |   ├── Source\n|   |   ├── FileCoverage\n|   |   └── Job\n|   |       ├── Artifact\n|   |       ├── ItemStat\n|   |       └── TestCase\n|   |           ├── Artifact\n|   |           └── ItemStat\n|   ├── ChangeRequest\n|   |   └── Revision\n|   └── Source\n|       ├── Author\n|       ├── Patch\n|       └── Revision\n|           └── Author\n└── User\n    ├── Email\n    └── Identity\n```\n\n### Hooks\n\nA subset of APIs are exposed using simple hook credentials. These credentials are coupled to a provider (e.g. `travis-ci`) and a single repository.\n\nTo create a new hook:\n\n```\nzeus hooks add https://github.com/getsentry/zeus.git travis-ci\n```\n\nUsing the subpath, you'll be able to access several endpoints:\n\n- `{prefix}/builds/{build-external-id}`\n- `{prefix}/builds/{build-external-id}/jobs/{job-external-id}`\n- `{prefix}/builds/{build-external-id}/jobs/{job-external-id}/artifacts`\n\nThe prefix will be generated for you as part of the new hook, and is made up of the Hook's GUID and it's signature:\n\nhttp://example.com/hooks/{hook-id}/{hook-signature}/{path}\n\nEach endpoint takes an external ID, which is used as a unique query parameter. The constraints are coupled to the parent object. For example, to create or patch a build:\n\n```\nPOST http://example.com/hooks/{hook-id}/{hook-signature}/builds/abc\n```\n\nThis will look for a Build object with the following characteristics:\n\n- `provider={Hook.provider}`\n- `external_id=abc`\n- `repository_id={Hook.repository_id}`\n\nIf a match is found, it will be updated with the given API parameters. If it isn't found, it will be created. All of these operations are treated like a standard UPSERT (UPDATE IF EXISTS or INSERT).\n\nThe process for publishing data generally looks like this:\n\n1. if applicable, upsert a change request and its source association\n2. upsert the build's basic parameters\n3. upsert the detailed job parameters\n4. publish artifacts\n\nThese actions can be also performed manually (without using the native webhooks) with `zeus-cli` (recommended) or `curl`.\n\n### Updating data with `zeus-cli`\n\nMore information (installation instructions, documentation) about `zeus-cli` can be found on its project's page: https://github.com/getsentry/zeus-cli\n\n`zeus-cli` is a command line tool that facilitates interaction with Zeus API for actions such as updating jobs or uploading artifacts.\n\nThe following command creates a build and a job for a given `git` revision:\n\n```shell\nzeus job update -b $MY_BUILD_ID -j $MY_JOB_ID  --ref=$MY_REF_ID\n```\n\nAnd here's how you upload an artifact:\n\n```shell\nzeus upload -b $MY_BUILD_ID -j $MY_JOB_ID -t 'text/xml+coverage' coverage.xml\n```\n\n### Updating data with `curl`\n\nHere's an example of how you can publish job details without the native webhooks with `curl` from Travis:\n\n```shell\n#!/bin/bash -eu\nif [[ \"$TRAVIS_PULL_REQUEST\" != \"false\" ]]; then\n    BUILD_LABEL=\"PR #${TRAVIS_PULL_REQUEST}\"\nelse\n    BUILD_LABEL=\"\"\nfi\n\n# ensure the build exists\ncurl $ZEUS_HOOK_BASE/builds/$TRAVIS_BUILD_NUMBER \\\n    -X POST \\\n    -H 'Content-Type: application/json' \\\n    -d \"{\\\"label\\\": \\\"${BUILD_LABEL}\\\", \\\"ref\\\": \\\"$TRAVIS_COMMIT\\\", \\\"url\\\": \\\"https://travis-ci.org/${TRAVIS_REPO_SLUG}/builds/${TRAVIS_BUILD_ID}\\\"}\"\n\n# upsert current job details\ncurl $ZEUS_HOOK_BASE/builds/$TRAVIS_BUILD_NUMBER/jobs/$TRAVIS_JOB_NUMBER \\\n    -X POST \\\n    -H 'Content-Type: application/json' \\\n    -d \"{\\\"status\\\": \\\"$1\\\", \\\"result\\\": \\\"$2\\\", \\\"url\\\": \\\"https://travis-ci.org/${TRAVIS_REPO_SLUG}/jobs/${TRAVIS_JOB_ID}\\\", \\\"allow_failure\\\": ${TRAVIS_ALLOW_FAILURE}}\"\n```\n\nFrom there you can submit artifacts using `zeus-cli` and its standard mechanisms.\n","funding_links":["https://sentry.io/pricing/","https://sentry.io/"],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetsentry%2Fzeus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgetsentry%2Fzeus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetsentry%2Fzeus/lists"}