{"id":16584906,"url":"https://github.com/mikaelvesavuori/github-dashboards","last_synced_at":"2025-07-22T04:32:50.875Z","repository":{"id":213665746,"uuid":"734631268","full_name":"mikaelvesavuori/github-dashboards","owner":"mikaelvesavuori","description":"Visualize your GitHub repositories and their workflow statuses 📈 like no thing at all 😎","archived":false,"fork":false,"pushed_at":"2024-02-02T13:56:58.000Z","size":630,"stargazers_count":10,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-09T05:51:11.900Z","etag":null,"topics":["aws","dashboards","github","serverless","visualization"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/mikaelvesavuori.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-12-22T07:27:45.000Z","updated_at":"2024-12-30T22:28:54.000Z","dependencies_parsed_at":"2024-02-02T15:05:53.363Z","dependency_job_id":null,"html_url":"https://github.com/mikaelvesavuori/github-dashboards","commit_stats":null,"previous_names":["mikaelvesavuori/github-dashboards"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mikaelvesavuori/github-dashboards","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikaelvesavuori%2Fgithub-dashboards","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikaelvesavuori%2Fgithub-dashboards/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikaelvesavuori%2Fgithub-dashboards/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikaelvesavuori%2Fgithub-dashboards/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mikaelvesavuori","download_url":"https://codeload.github.com/mikaelvesavuori/github-dashboards/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikaelvesavuori%2Fgithub-dashboards/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266427994,"owners_count":23926911,"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","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"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":["aws","dashboards","github","serverless","visualization"],"created_at":"2024-10-11T22:46:10.992Z","updated_at":"2025-07-22T04:32:50.851Z","avatar_url":"https://github.com/mikaelvesavuori.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GitHub Dashboards\n\n## Visualize your GitHub repositories and their workflow statuses 📈 like no thing at all 😎\n\nThis is a ready-to-use solution with a serverless backend (AWS: API Gateway, Lambda, DynamoDB) and a simple frontend to render the dashboards.\n\nWorks with both private and public repositories.\n\n![Visualization](screen.png)\n\n## Solution\n\nCalls are made from the front-end to the back-end without any authorization. It's suggested you lock down the front-end with some applicable means, like an SSO layer or Cloudflare Access or something similar.\n\n_If you want to get data for private repositories you will need a \"classic\" GitHub personal access token (PAT) with permissions to use the `workflow` scope. If you are in an organization, make sure to authorize the use of the token against your organization._\n\nFrom the Lambda function, it will first check a hash of the input in DynamoDB as a type of cache. If the cache has content and it's fresher than a minute, return it. Else go to GitHub to retrieve workflow data, transform it a bit, pass it to Shields.io to generate the SVG badge, and then finally return all of it.\n\n_If you're curious, each dashboard component is ~1200 bytes so that should give you an idea for the DynamoDB usage._\n\n**Feel free to upgrade it with nicer visuals, API keys or security, client-side caching, or anything else you fancy!**\n\n## Prerequisites\n\n- Recent [Node.js](https://nodejs.org/en/) (ideally 20+) installed.\n- Amazon Web Services (AWS) account with sufficient permissions so that you can deploy infrastructure.\n- Ideally some experience with [Serverless Framework](https://www.serverless.com) as that's what we will use to deploy the service and infrastructure.\n- You will need to deploy the stack prior to working with it locally as it uses actual infrastructure even in local mode.\n\n## Installation\n\nClone, fork, or download the repo as you normally would. Run `npm install`.\n\n## Deployment\n\nRun `npm run deploy` once you are authenticated with AWS. You will get a URL for your endpoint - use this in the front-end code.\n\nFor the front-end, just host it on a static website host like Cloudflare Pages or Netlify.\n\n## Commands\n\nThe below commands are the most critical ones. See `package.json` for more commands! Substitute `npm` for `yarn` or whatever floats your boat.\n\n- `npm start`: Run Serverless Framework in offline mode\n- `npm test`: Run tests on the codebase\n- `npm run deploy`: Deploy with Serverless Framework\n- `npm run build`: Package and build the code with Serverless Framework\n- `npm run teardown`: Removes the deployed stack\n\n## Configuration\n\n### Required\n\nYou have to set the following in `serverless.yml`:\n\n- `custom.config.awsAccountNumber`: Your AWS account number.\n- `GITHUB_TOKEN` must be set if you want to call private repositories.\n\n_Optionally you can use AWS Secrets Manager instead of hard-coding the GitHub token. There is some code prepped for this, but you will have to manually create the secret in your AWS account._\n\nIn `frontend/index.html`, you will have to modify:\n\n- The endpoint for the `getData()` function, as well as the ingoing payload.\n\n## Example API call\n\n### Get dashboard data\n\n#### Request\n\n`POST {{BASE_URL}}/`\n\n```json\n[\n  {\n    \"owner\": \"mikaelvesavuori\",\n    \"repo\": \"dorametrix\",\n    \"ref\": \"main\"\n  },\n  ...\n]\n```\n\n#### Successful response\n\nExample below. One object per successful request.\n\n```json\n[\n  {\n    \"conclusion\": \"success\",\n    \"status\": \"completed\",\n    \"owner\": \"mikaelvesavuori\",\n    \"repo\": \"dorametrix\",\n    \"ref\": \"main\",\n    \"badge\": \"\u003csvg xmlns=\\\"http://www.w3.org/2000/svg\\\" xmlns:xlink=\\\"http://www.w3.org/1999/xlink\\\" width=\\\"104\\\" height=\\\"20\\\" role=\\\"img\\\" aria-label=\\\"main: completed\\\"\u003e\u003ctitle\u003emain: completed\u003c/title\u003e\u003clinearGradient id=\\\"s\\\" x2=\\\"0\\\" y2=\\\"100%\\\"\u003e\u003cstop offset=\\\"0\\\" stop-color=\\\"#bbb\\\" stop-opacity=\\\".1\\\"/\u003e\u003cstop offset=\\\"1\\\" stop-opacity=\\\".1\\\"/\u003e\u003c/linearGradient\u003e\u003cclipPath id=\\\"r\\\"\u003e\u003crect width=\\\"104\\\" height=\\\"20\\\" rx=\\\"3\\\" fill=\\\"#fff\\\"/\u003e\u003c/clipPath\u003e\u003cg clip-path=\\\"url(#r)\\\"\u003e\u003crect width=\\\"37\\\" height=\\\"20\\\" fill=\\\"#555\\\"/\u003e\u003crect x=\\\"37\\\" width=\\\"67\\\" height=\\\"20\\\" fill=\\\"#4c1\\\"/\u003e\u003crect width=\\\"104\\\" height=\\\"20\\\" fill=\\\"url(#s)\\\"/\u003e\u003c/g\u003e\u003cg fill=\\\"#fff\\\" text-anchor=\\\"middle\\\" font-family=\\\"Verdana,Geneva,DejaVu Sans,sans-serif\\\" text-rendering=\\\"geometricPrecision\\\" font-size=\\\"110\\\"\u003e\u003ctext aria-hidden=\\\"true\\\" x=\\\"195\\\" y=\\\"150\\\" fill=\\\"#010101\\\" fill-opacity=\\\".3\\\" transform=\\\"scale(.1)\\\" textLength=\\\"270\\\"\u003emain\u003c/text\u003e\u003ctext x=\\\"195\\\" y=\\\"140\\\" transform=\\\"scale(.1)\\\" fill=\\\"#fff\\\" textLength=\\\"270\\\"\u003emain\u003c/text\u003e\u003ctext aria-hidden=\\\"true\\\" x=\\\"695\\\" y=\\\"150\\\" fill=\\\"#010101\\\" fill-opacity=\\\".3\\\" transform=\\\"scale(.1)\\\" textLength=\\\"570\\\"\u003ecompleted\u003c/text\u003e\u003ctext x=\\\"695\\\" y=\\\"140\\\" transform=\\\"scale(.1)\\\" fill=\\\"#fff\\\" textLength=\\\"570\\\"\u003ecompleted\u003c/text\u003e\u003c/g\u003e\u003c/svg\u003e\"\n  },\n  ...\n]\n```\n\n## References\n\n- [GitHub: Workflow Runs](https://docs.github.com/en/rest/actions/workflow-runs?apiVersion=2022-11-28)\n- [GitHub: Creating tokens](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)\n- [Shields.io badges](https://shields.io/badges)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikaelvesavuori%2Fgithub-dashboards","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikaelvesavuori%2Fgithub-dashboards","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikaelvesavuori%2Fgithub-dashboards/lists"}