main 15313523fb57 cached
35 files
489.5 KB
120.4k tokens
26 symbols
1 requests
Download .txt
Showing preview only (507K chars total). Download the full file or copy to clipboard to get everything.
Repository: chriskinsman/github-action-dashboard
Branch: main
Commit: 15313523fb57
Files: 35
Total size: 489.5 KB

Directory structure:
gitextract_680p5qqh/

├── .dockerignore
├── .eslintrc.js
├── .github/
│   └── workflows/
│       └── ci.yaml
├── .gitignore
├── .nvmrc
├── Dockerfile
├── LICENSE
├── README.md
├── actions.js
├── client/
│   ├── .gitignore
│   ├── babel.config.js
│   ├── jsconfig.json
│   ├── package.json
│   ├── public/
│   │   ├── index.html
│   │   └── robots.txt
│   ├── src/
│   │   ├── App.vue
│   │   ├── components/
│   │   │   └── actiondashboard.vue
│   │   ├── main.js
│   │   └── plugins/
│   │       ├── vue-socket-io-extended.js
│   │       └── vuetify.js
│   └── vue.config.js
├── configure.js
├── getinstallationid.js
├── github.js
├── index.js
├── jest.config.js
├── package.json
├── routes.js
├── runstatus.js
├── tests/
│   ├── integration/
│   │   └── github.test.js
│   └── unit/
│       ├── actions.test.js
│       ├── mock_data.js
│       ├── runstatus.test.js
│       └── webooks.test.js
└── webhooks.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
*.crt
*.key
.dockerignore
.git
.gitignore
.idea
.jshintrc
commit.sha
# dist
# dist/*
Dockerfile
#node_modules/*
README.md
.editorconfig
.browserslistrc
jsconfig.json
.env*
.env.local
.env.*.local

================================================
FILE: .eslintrc.js
================================================
module.exports = {
  env: {
    browser: true,
    es2020: true,
  },
  parser: "@babel/eslint-parser",
  parserOptions: {
    ecmaVersion: 11,
    requireConfigFile: false,
    sourceType: "module",
  },
  rules: {},
};


================================================
FILE: .github/workflows/ci.yaml
================================================
name: ci
on:
  workflow_dispatch:
  push:
  # pull_request:
  #   branches: main
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - uses: actions/setup-node@v2
        with:
          cache: "npm"
          cache-dependency-path: "**/package-lock.json"
          node-version-file: ".nvmrc"
      - name: Install packages for server
        run: npm ci --ignore-scripts
      - name: Install Packages for client
        run: npm ci --ignore-scripts
        working-directory: ./client
      - name: Run tests
        run: npm run test
      - name: Eliminate devDependencies
        run: npm prune --production
      - name: Build web client
        run: DOCKER_BUILD=true npm run build
        working-directory: ./client
      - name: Docker meta
        id: docker_meta
        uses: crazy-max/ghaction-docker-meta@v1
        with:
          images: ghcr.io/${{ github.repository_owner }}/github-action-dashboard
          tag-sha: true
          tag-edge: true
          tag-latest: true
          github-token: ${{ secrets.GITHUB_TOKEN }}
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v1
      - name: Set up Docker Buildx
        id: buildx
        uses: docker/setup-buildx-action@v1
        #with:
        # hack for https://github.com/docker/build-push-action/issues/126
        #driver-opts: image=moby/buildkit:master
      - name: Available platforms
        run: echo ${{ steps.buildx.outputs.platforms }}
      - name: Login to GitHub Container Registry
        if: github.event_name != 'pull_request'
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GH_CR_PAT }}
      - name: Build and push
        id: docker_build
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./Dockerfile
          push: ${{ github.event_name != 'pull_request' }}
          platforms: linux/amd64,linux/arm64
          tags: ${{ steps.docker_meta.outputs.tags }}
          cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/github-action-dashboard:edge
          cache-to: type=inline
      - name: Image digest
        run: echo ${{ steps.docker_build.outputs.digest }} #this is for logging.


================================================
FILE: .gitignore
================================================
.DS_Store
node_modules
/dist
/client/dist

# local env files
.env
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

wallaby.conf.js


================================================
FILE: .nvmrc
================================================
v16.13.1

================================================
FILE: Dockerfile
================================================
FROM node:16-alpine as base
LABEL org.opencontainers.image.source=https://github.com/ChrisKinsman/github-action-dashboard
WORKDIR /github-action-dashboard

# ---- Dependencies
FROM base as dependencies
RUN apk add --no-cache --virtual .gyp python3 make g++ git openssh

#
# ---- npm ci production
FROM dependencies as npm
COPY package.json package-lock.json ./
COPY node_modules ./node_modules
RUN npm rebuild

# production stage & clean up
FROM base as release
ENV NODE_ENV production
COPY client/dist ./client/dist/
COPY actions.js configure.js getinstallationid.js github.js index.js routes.js runstatus.js webhooks.js ./
COPY --from=npm /github-action-dashboard/node_modules ./node_modules


================================================
FILE: LICENSE
================================================
(The MIT License)

Copyright (c) 2009-2014 TJ Holowaychuk <tj@vision-media.ca>

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

================================================
FILE: README.md
================================================
# GitHub Action Dashboard - No Longer Supported

My team is no longer using this for monitoring our GitHub actions.  Feel free to fork and improve!

![ScreenShot](https://github.com/ChrisKinsman/github-action-dashboard/blob/main/docs/images/ActionDashboardScreenShot.png)

When our current CI/CD provider shutdown I found myself evaluating GitHub actions as an alternative. Great solution with one problem. There was no single pane of glass to see the status of all the builds in our GitHub organization. Instead you had to go into each repo, check the action status, etc.

I looked around for solutions to the problem and found very few. Meercode was a SaaS that was available but connecting it to my GitHub account at the time I tested it it required granting it permission to act on my behalf. I couldn't see a way that my employer would be cool with that.

A self hosted solution seemed like the way to go but I couldn't really find any. Surprising given the popularity of GitHub.

## Limitations

- Single organization/username. Currently the dashboard requires you to specify the organization or the username of the repositories which show on the dashboard. It doesn't support multiple organizations or usernames.

## How it works

- Upon startup all repositories for the organization/username are iterated.
- Each repository is checked for workflows.
- Each workflow has it's runs listed
- The most recent run for each branch is returned.

Every 15 minutes this process is repeated. Fifteen minutes was chosen so as to not hit GitHub API limits.

When you click the refresh button in the dashboard it refreshes all runs associated with that workflow across all branches. This is refreshed server side so that other consumers of the dashboard also see the update prior to the refresh of all data.

When a workflow_run webhook is received the the central data is updated and the update is sent to all clients to refresh their displays via websockets.

## Setup GitHub App

The dashboard runs as a GitHub App. It does not automatically register itself as a GitHub app. Automatic registration is difficult if the dashboard is private and not exposed on the internet. Instead you need to manually setup a GitHub app for your organization or username.

Steps:

- Go into the settings for your organization or username
- Click Developer Settings
- Click GitHub Apps
- Click New GitHub App
  - Add an app name and homepage url
  - Put your endpoint in for the webhook url - This is optional. If you don't configure this the dashboard lag action status. For testing you can use https://smee.io but in production you will likely have to look at a solution like https://ngrok.com or https://inlets.dev
  - Put in a webhook secret
  - Repository Permissions:
    - Action: read-only
  - Subscribe to events:
    - Workflow run
  - Where can this GibHub App be installed: Only on this account
  - Should look like: ![General Settings Screen](https://github.com/ChrisKinsman/github-action-dashboard/blob/main/docs/images/ActionDashboardNewGitHubApp.png)
  - Click Create GitHub App
- You should now be on the general settings page for the app
- Click Generate a new client secret and save off the client secret as it will disappear after you navigate off the page.
- Click Generate a private key. It will download a .pem file that you need to base64 encode.
- Should look like: ![General Settings Screen](https://github.com/ChrisKinsman/github-action-dashboard/blob/main/docs/images/ActionDashboardGeneralSettings.png)
- Change to Install App page: ![General Settings Screen](https://github.com/ChrisKinsman/github-action-dashboard/blob/main/docs/images/ActionDashboardInstall.png)
- Click Install
- You will get a permissions page like this: ![General Settings Screen](https://github.com/ChrisKinsman/github-action-dashboard/blob/main/docs/images/ActionDashboardPermissions.png)
- Click install

## Configuring Dashboard

The dashboard has all of it's parameters passed via environment variables.

### Variables

- PORT - Optional, defaults to 8080. Port site should run on.
- GITHUB_USERNAME or GITHUB_ORG - Only one is valid. If both are specified GITHUB_ORG takes precedence and the GITHUB_USERNAME is ignored.
- GITHUB_APPID - The AppId from the GitHub App general settings page.
- GITHUB_APP_PRIVATEKEY - The base64 encoded private key from the GitHub App general settings page.
- GITHUB_APP_CLIENTID - The client id from the GitHub App general settings page.
- GITHUB_APP_CLIENTSECRET - The client secret from the GitHub App general settings page.
- GITHUB_APP_INSTALLATIONID - Installation id that can be retrieved using steps in the next section.
- GITHUB_APP_WEBHOOK_SECRET - Optional. If you don't supply the dashboard will not setup webhooks and only update every 15 minutes.
- GITHUB_APP_WEBHOOK_PORT - Optional, defaults to 8081. If set to the same as PORT must also specify GITHUB_APP_WEBHOOK_PATH
- GITHUB_APP_WEBHOOK_PATH - Optional if WebHooks running on different port than main site, defaults to /, if running on the same port defaults to /webhook.
- LOOKBACK_DAYS - Optional, defaults to 7. Number of days to look in the past for workflow runs.
- DEBUG=action-dashboard:\* - Optional setting to help in debugging

### Installation Id

GitHub doesn't make the installation id super obvious in the UI. Here is how to obtain the installation id.

- Go into the settings for your organization or username
- Click Developer Settings
- Click GitHub Apps
- Click Configure on GitHub Action Dashboard
- In the URL, the digits after the slash are your installation id.

Alternatively I have provided a utility to obtain the installation id. You will need all the variables from the previous section with the exception of GITHUB_APP_INSTALLATIONID set to do this.

#### Option 1

Requires docker installed locally.

```bash
docker run --rm -t --env GITHUB_USERNAME=XXXXXXX --env GITHUB_APPID=XXXXXX --env GITHUB_APP_PRIVATEKEY=XXXXXXXXXXXXXXXXXXX --env GITHUB_APP_CLIENTID=XXX.XXXXXXXXXXXXXXXX --env GITHUB_APP_CLIENTSECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ghcr.io/chriskinsman/github-action-dashboard:edge node getinstallationid.js
```

#### Option 2

Requires nodejs installed locally.

```bash
npm ci
GITHUB_USERNAME=XXXXXXX GITHUB_APPID=XXXXXX GITHUB_APP_PRIVATEKEY=XXXXXXXXXXXXXXXXXXXXX GITHUB_APP_CLIENTID=XXX.XXXXXXXXXXXXXXXX GITHUB_APP_CLIENTSECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX node getinstallationid.js
```

## Running Dashboard

#### Option 1

Requires docker installed locally.

```bash
docker run --rm -td -p 8080:8080 --env GITHUB_USERNAME=XXXXXXX --env GITHUB_APPID=XXXXXX --env GITHUB_APP_PRIVATEKEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX --env GITHUB_APP_CLIENTID=XXX.XXXXXXXXXXXXXXXX --env GITHUB_APP_CLIENTSECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --env GITHUB_APP_INSTALLATIONID=XXXXXXX ghcr.io/chriskinsman/github-action-dashboard:edge node index.js
```

#### Option 2

Requires nodejs installed locally.

```bash
npm ci
cd client
npm ci
npm run build
cd ..
GITHUB_USERNAME=XXXXXXX GITHUB_APPID=XXXXXX GITHUB_APP_PRIVATEKEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX GITHUB_APP_CLIENTID=XXX.XXXXXXXXXXXXXXXX GITHUB_APP_CLIENTSECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX GITHUB_APP_INSTALLATIONID=XXXXXXX node index.js
```

Open your browser to http://localhost:8080

## Debugging tips

Debugging webhooks can be hard.

Couple tips:

1. Run the full app outside vue-cli
2. Use the smee-client to proxy the webhook:

```bash
smee --port 8081
```

Then take the proxy endpoint and update your GitHub App webhook with it


================================================
FILE: actions.js
================================================
const debug = require("debug")("action-dashboard:actions");
const _ = require("lodash");
const dayjs = require("dayjs");
const pLimit = require("p-limit");

class Actions {
  constructor(gitHub, runStatus, lookbackDays) {
    this._gitHub = gitHub;
    this._runStatus = runStatus;
    // Cache all workflows to speed up refresh
    this._runs = [];
    this._refreshingRuns = false;
    this._lookbackDays = lookbackDays;
  }

  start() {
    debug("Performing initial refreshRuns");
    // Load the initial set
    this.refreshRuns();

    debug("Setting interval to refreshRuns at 15m");
    // Refresh by default every fifteeen minutes
    setInterval(this.refreshRuns, 1000 * 60 * 15);
  }

  async getMostRecentRuns(repoOwner, repoName, workflowId) {
    try {
      const daysAgo = dayjs().subtract(this._lookbackDays, "day");
      const runs = await this._gitHub.listWorkflowRuns(
        repoOwner,
        repoName,
        workflowId
      );
      if (runs.length > 0) {
        const groupedRuns = _.groupBy(runs, "head_branch");
        const rows = _.reduce(
          groupedRuns,
          (result, runs, branch) => {
            debug(`branch`, branch);
            if (daysAgo.isBefore(dayjs(runs[0].created_at))) {
              debug(`adding run.id: ${runs[0].id}`);
              result.push({
                runId: runs[0].id,
                repo: runs[0].repository.name,
                owner: repoOwner,
                workflowId: workflowId,
                runNumber: runs[0].run_number,
                workflow: runs[0].name,
                branch: runs[0].head_branch,
                sha: runs[0].head_sha,
                message: runs[0].head_commit.message,
                committer: runs[0].head_commit.committer.name,
                status:
                  runs[0].status === "completed"
                    ? runs[0].conclusion
                    : runs[0].status,
                createdAt: runs[0].created_at,
                updatedAt: runs[0].updated_at,
              });
            } else {
              debug(
                `skipping run.id: ${runs[0].id} created_at: ${runs[0].created_at}`
              );
            }

            return result;
          },
          []
        );

        debug(
          `getting duration of runs owner: ${repoOwner}, repo: ${repoName}, workflowId: ${workflowId}`
        );

        // Get durations of runs
        const limit = pLimit(10);
        const getUsagePromises = rows.map((row) => {
          return limit(async () => {
            const usage = await this._gitHub.getUsage(
              repoOwner,
              repoName,
              workflowId,
              row.runId
            );
            if (usage?.run_duration_ms) {
              row.durationMs = usage.run_duration_ms;
            }

            return row;
          });
        });

        const rowsWithDuration = await Promise.all(getUsagePromises);

        debug(
          `most recent runs owner: ${repoOwner}, repo: ${repoName}, workflowId: ${workflowId}`,
          rowsWithDuration
        );
        return rows;
      } else {
        return [];
      }
    } catch (e) {
      console.error("Error getting runs", e);
      return [];
    }
  }

  mergeRuns(runs) {
    // Merge into cache
    runs.forEach((run) => {
      debug(`merging run`, run);
      const index = _.findIndex(this._runs, {
        workflowId: run.workflowId,
        branch: run.branch,
      });
      if (index >= 0) {
        this._runs[index] = run;
      } else {
        this._runs.push(run);
      }
      this._runStatus.updatedRun(run);
    });

    debug("merged runs", this._runs);
  }

  refreshRuns = async () => {
    // Prevent re-entrant calls
    if (this._refreshingRuns) {
      return;
    }

    debug("Starting refreshing runs");
    try {
      this._refreshingRuns = true;
      const repos = await this._gitHub.listRepos();
      for (const repo of repos) {
        debug(`repo: ${repo.name}`);
        const workflows = await this._gitHub.listWorkflowsForRepo(
          repo.name,
          repo.owner.login
        );
        if (workflows.length > 0) {
          for (const workflow of workflows) {
            debug(`workflow: ${workflow.name}`);
            const runs = await this.getMostRecentRuns(
              repo.owner.login,
              repo.name,
              workflow.id
            );
            // Not using apply or spread in case there are a large number of runs returned
            this.mergeRuns(runs);
          }
        }
      }
    } catch (e) {
      console.error("Error getting initial data", e);
    } finally {
      debug("Finished refreshing runs");
      this._refreshingRuns = false;
    }
  };

  async refreshWorkflow(repoOwner, repoName, workflowId) {
    const runs = await this.getMostRecentRuns(repoOwner, repoName, workflowId);
    this.mergeRuns(runs);
  }

  getInitialData() {
    debug(`getInitialData this._runs.length: ${this._runs.length}`);
    if (this._runs.length === 0 && !this._refreshingRuns) {
      debug("getInitialData calling refreshRuns");
      this.refreshRuns();
    }

    return this._runs;
  }
}

module.exports = Actions;


================================================
FILE: client/.gitignore
================================================
.DS_Store
node_modules
/dist


# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?


================================================
FILE: client/babel.config.js
================================================
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ]
}


================================================
FILE: client/jsconfig.json
================================================
{
  "compilerOptions": {
    "target": "es2015",
    "module": "esnext",
    "baseUrl": "./",
    "paths": {
      "@/*": ["components/*"]
    }
  },
  "include": [
    "src/**/*.vue",
    "src/**/*.js"
  ]
}

================================================
FILE: client/package.json
================================================
{
  "name": "client",
  "version": "1.6.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "DOCKER_BUILD=true vue-cli-service build",
    "lint": "DOCKER_BUILD=true vue-cli-service lint"
  },
  "dependencies": {
    "axios": "^0.27.2",
    "core-js": "^3.22.5",
    "dayjs": "^1.11.2",
    "lodash-es": "^4.17.21",
    "socket.io-client": "^4.5.1",
    "vue": "^2.6.14",
    "vue-socket.io-extended": "^4.2.0",
    "vuetify": "^2.6.6"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.15",
    "@vue/cli-plugin-eslint": "^4.5.15",
    "@vue/cli-service": "~4.5.15",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^6.2.2",
    "sass": "^1.32.13",
    "sass-loader": "^10.0.0",
    "vue-cli-plugin-vuetify": "~2.4.8",
    "vue-template-compiler": "^2.6.14",
    "vuetify-loader": "^1.7.3"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

================================================
FILE: client/public/index.html
================================================
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <meta name="robots" content="noindex,nofollow">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>


================================================
FILE: client/public/robots.txt
================================================
User-agent: *
Disallow: /

================================================
FILE: client/src/App.vue
================================================
<template>
    <v-app>
        <v-app-bar app color="primary" dark>
            <v-app-bar-title>{{ owner }} Action Dashboard</v-app-bar-title>
        </v-app-bar>

        <v-main>
            <ActionDashboard />
        </v-main>
    </v-app>
</template>

<script>
import ActionDashboard from "./components/actiondashboard.vue";
import axios from "axios";

export default {
    name: "App",
    mounted() {
        axios
            .get("/api/owner")
            .then((result) => {
                console.log("Setting owner to " + result.data);
                this.owner = result.data;
            })
            .catch((err) => {
                console.error(err);
            });
    },
    components: {
        ActionDashboard,
    },
    data: () => ({
        owner: "PlaceholderTitleForOwner",
    }),
};
</script>


================================================
FILE: client/src/components/actiondashboard.vue
================================================
<template>
    <v-container :fluid="true">
        <v-data-table
            :headers="headers"
            :items="runs"
            item-key="name"
            class="elevation-1"
            :search="search"
            :custom-filter="filterOnlyCapsText"
            :disable-pagination="true"
            :hide-default-footer="true"
            :loading="loading"
            loading-text="Loading runs..."
            sort-by="createdAt"
            :sort-desc="true"
        >
            <template v-slot:top>
                <v-text-field v-model="search" label="Search" class="mx-4"></v-text-field>
            </template>
            <template v-slot:item.workflow="{ item }">
                <a :href="`https://github.com/${item.owner}/${item.repo}/actions?query=workflow%3A${item.workflow}`" target="_blank">{{ item.workflow }}</a>
            </template>
            <template v-slot:item.message="{ item }">
                <a :href="`https://github.com/${item.owner}/${item.repo}/actions/runs/${item.runId}`" target="_blank">{{ item.message }}</a>
            </template>
            <template v-slot:item.sha="{ item }">
                <a :href="`https://github.com/${item.owner}/${item.repo}/commit/${item.sha}`" target="_blank">{{ item.sha.substr(0, 8) }}</a>
            </template>

            <template v-slot:item.status="{ item }">
                <v-chip :color="getColor(item.status)">
                    {{ item.status }}
                </v-chip>
            </template>

            <template v-slot:item.createdAt="{ item }">
                <div>
                    <div>{{ item.createdAt | formattedDate }}</div>
                    <div>{{item.createdAt | formattedTime}}</div>
                </div>
            </template>

            <template v-slot:item.durationMs="{ item }">
                {{ item.durationMs | formattedDuration }}
            </template>

            <template v-slot:item.actions="{ item }">
                <v-icon small @click="refreshRun(item)"> mdi-refresh </v-icon>
            </template>
        </v-data-table>
    </v-container>
</template>

<script>
import axios from "axios";
import findIndex from "lodash-es/findIndex";
import * as dayjs from "dayjs";
import duration from "dayjs/plugin/duration";
dayjs.extend(duration);

export default {
    sockets: {
        updatedRun(run) {
            console.log("updatedRun runId: " + run.runId);
            const index = findIndex(this.runs, { workflowId: run.workflowId, branch: run.branch });
            if (index >= 0) {
                this.$set(this.runs, index, run);
            } else {
                this.runs.push(run);
            }
        },
    },
    mounted() {
        this.getData();
    },
    data() {
        return {
            search: "",
            runs: [],
            loading: false,
        };
    },
    computed: {
        headers() {
            return [
                { text: "Repository", align: "start", value: "repo" },
                { text: "Workflow", value: "workflow" },
                { text: "Branch", value: "branch" },
                { text: "Status", value: "status" },
                { text: "Commit", value: "sha" },
                { text: "Message", value: "message" },
                { text: "Committer", value: "committer" },
                { text: "Started", value: "createdAt", align: "right"},
                { text: "Duration", value: "durationMs", align: "right"},
                { text: "", value: "actions", sortable: false },
            ];
        },
    },
    filters: {
        formattedDate(val) {
            if(val) {
                return dayjs(val).format("YYYY-MM-DD");
            }
            else return val;
        },
        formattedTime(val) {
            if(val) {
                return dayjs(val).format("h:mm A")
            }
        },
        formattedDuration(val) {
            if(val) {
                let format = "";
                if(val >= 3.6e+6) {
                    format = "H[h] m[m] s[s]";
                }
                else if(val >= 60000 ) {
                    format = "m[m] s[s]";
                }
                else {
                    format = "s[s]";
                }
                return dayjs.duration(val).format(format);
            }
            else return val;
        }
    },
    methods: {
        getData() {
            this.loading = true;
            axios
                .get("/api/initialData")
                .then((result) => {
                    console.log("getData results");
                    this.runs = result.data;
                })
                .catch((err) => {
                    console.log("getData error");
                    console.error(err);
                })
                .finally(() => {
                    console.log("getData finally");
                    this.loading = false;
                });
        },
        refreshRun(run) {
            // This
            run.status = "Refreshing";
            // Get all new runs for workflow_id
            axios.get(`/api/runs/${run.owner}/${run.repo}/${run.workflowId}`).catch((err) => {
                console.log("refreshRun", err);
            });
        },
        filterOnlyCapsText(value, search) {
            return value != null && search != null && typeof value === "string" && value.toString().indexOf(search) !== -1;
        },
        getColor(status) {
            switch (status) {
                case "success":
                    return "green";

                case "failure":
                    return "red";

                case "in_progress":
                case "queued":
                    return "yellow";

                default:
                    return "transparent";
            }
        },
    },
};
</script>

<style lang="scss">
.v-data-table-header { 
    th {
        white-space: nowrap;
    }

    th:nth-child(8) {
        min-width: 120px;
    }
}
</style>

================================================
FILE: client/src/main.js
================================================
import Vue from 'vue'
import App from './App.vue'
import vuetify from './plugins/vuetify';
import vueSocketIoExtended from './plugins/vue-socket-io-extended';

Vue.config.productionTip = false

new Vue({
  vueSocketIoExtended,
  vuetify,
  render: h => h(App)
}).$mount('#app')


================================================
FILE: client/src/plugins/vue-socket-io-extended.js
================================================
import Vue from 'vue';
import VueSocketIOExt from 'vue-socket.io-extended';
import { io } from 'socket.io-client';

const socket = io();

Vue.use(VueSocketIOExt, socket);

export default {
    sockets: {
        connect() {
            console.log('socket connected');
        }
    }
}

================================================
FILE: client/src/plugins/vuetify.js
================================================
import Vue from 'vue';
import Vuetify from 'vuetify/lib/framework';

Vue.use(Vuetify);

export default new Vuetify({
});


================================================
FILE: client/vue.config.js
================================================
const configureAPI = require('../configure');

module.exports = {
  chainWebpack: config => {
    config.plugin('html').tap(args => {
      args[0].title = "Action Dashboard"
      return args;
    })
  },
  devServer: {
    before: configureAPI.before,
    // Can't figure out how to connect up socket.io as part of webpack devServer
    //after: configureAPI.after
  },

  transpileDependencies: [
    'vuetify'
  ]
};


================================================
FILE: configure.js
================================================
const bodyParser = require("body-parser");
const debug = require("debug")("action-dashboard:configure");
const express = require("express");
const path = require("path");
const Actions = require("./actions");
const GitHub = require("./github");
const Routes = require("./routes");
const RunStatus = require("./runstatus");
const WebHooks = require("./webhooks");

const baseDir = path.basename(process.cwd());
// Handle when server is started from vue-cli vs root
if (baseDir === "client") {
  debug("started from vue-cli");
  require("dotenv").config({ path: path.resolve(process.cwd(), "../.env") });
}
// Handle when server is started from
else {
  debug("started from index.js");
  require("dotenv").config();
}

debug("env", process.env);

const {
  PORT = 8080,
  LOOKBACK_DAYS = 7,
  GITHUB_APPID,
  GITHUB_APP_CLIENTID,
  GITHUB_APP_CLIENTSECRET,
  GITHUB_APP_INSTALLATIONID,
  GITHUB_APP_WEBHOOK_PORT = 8081,
  GITHUB_APP_WEBHOOK_SECRET,
  GITHUB_APP_WEBHOOK_PATH = "/",
  GITHUB_ORG,
  GITHUB_USERNAME,
} = process.env;

// Handles newlines \n in private key
const GITHUB_APP_PRIVATEKEY = Buffer.from(
  process.env.GITHUB_APP_PRIVATEKEY || "",
  "base64"
).toString("utf-8");

// For sharing runStatus across before/after stages
let _runStatus = null;

module.exports = {
  before: (app) => {
    debug("configure before");

    const gitHub = new GitHub(
      GITHUB_ORG,
      GITHUB_USERNAME,
      GITHUB_APPID,
      GITHUB_APP_PRIVATEKEY,
      GITHUB_APP_CLIENTID,
      GITHUB_APP_CLIENTSECRET,
      GITHUB_APP_INSTALLATIONID
    );
    _runStatus = new RunStatus();
    const actions = new Actions(gitHub, _runStatus, LOOKBACK_DAYS);
    const routes = new Routes(
      actions,
      process.env.GITHUB_ORG || process.env.GITHUB_USERNAME
    );
    const router = express.Router();

    routes.attach(router);

    app.use(bodyParser.json());
    app.use("/api", router);

    const webhooks = new WebHooks(
      PORT,
      GITHUB_APP_WEBHOOK_SECRET,
      GITHUB_APP_WEBHOOK_PORT,
      GITHUB_APP_WEBHOOK_PATH,
      gitHub,
      actions,
      app
    );

    // Start everything
    actions.start();
    webhooks.start();
  },
  after: (app, server) => {
    debug("configure after");

    // Attach socket.io to server
    _runStatus.start(server);
  },
};


================================================
FILE: getinstallationid.js
================================================
require('dotenv').config()
const { createAppAuth } = require("@octokit/auth-app");
const { Octokit } = require("@octokit/rest");

const _appId = process.env.GITHUB_APPID;
// Handles newlines \n in private key
const _privateKey = Buffer.from(process.env.GITHUB_APP_PRIVATEKEY || "", "base64").toString("utf-8");
const _clientId = process.env.GITHUB_APP_CLIENTID;
const _clientSecret = process.env.GITHUB_APP_CLIENTSECRET;

const octokit = new Octokit({
    auth: {
        appId: _appId,
        privateKey: _privateKey,
        clientId: _clientId,
        clientSecret: _clientSecret,
    },
    authStrategy: createAppAuth
});

octokit.apps.listInstallations()
    .then(response => {
        response.data.forEach((installation) => {
            console.log(`Account: ${installation.account.login}, installation id: ${installation.id}`);
        });
    })
    .catch(err => {
        console.error(err);
    });

================================================
FILE: github.js
================================================
const { createAppAuth } = require("@octokit/auth-app");
const { throttling } = require("@octokit/plugin-throttling");
const { retry } = require("@octokit/plugin-retry");
const { Octokit } = require("@octokit/rest");
const debug = require("debug")("action-dashboard:github");

class GitHub {
  constructor(
    _org,
    _user,
    _appId,
    _privateKey,
    _clientId,
    _clientSecret,
    _installationId
  ) {
    this._org = _org;
    this._user = _user;
    this._appId = _appId;
    this._privateKey = _privateKey;
    this._clientId = _clientId;
    this._clientSecret = _clientSecret;
    this._installationId = _installationId;

    const MyOctoKit = Octokit.plugin(throttling).plugin(retry);
    this._octokit = new MyOctoKit({
      auth: {
        appId: _appId,
        privateKey: _privateKey,
        clientId: _clientId,
        clientSecret: _clientSecret,
        installationId: _installationId,
      },
      authStrategy: createAppAuth,
      throttle: {
        onRateLimit: (retryAfter, options) => {
          console.error(
            `Request quota exhausted for request ${options.method} ${options.url}`
          );

          if (options.request.retryCount === 0) {
            // only retries once
            console.error(`Retrying after ${retryAfter} seconds!`);
            return true;
          }
        },
        onAbuseLimit: (retryAfter, options) => {
          console.error(
            `Abuse detected for request ${options.method} ${options.url}`
          );
        },
      },
    });

    // Allows us to use the dashboard for user based repos or org based repos
    this._listRepos = this._org
      ? this._octokit.repos.listForOrg
      : this._octokit.repos.listForUser;
    this._owner = this._org ? { org: this._org } : { username: this._user };

    debug("Using owner:", this._owner);
  }

  async listRepos() {
    try {
      const repos = await this._octokit.paginate(this._listRepos, this._owner);
      return repos;
    } catch (e) {
      console.error("Error getting repos", e);
      return [];
    }
  }

  async listWorkflowsForRepo(repoName, repoOwner) {
    try {
      const workflows = await this._octokit.paginate(
        this._octokit.actions.listRepoWorkflows,
        { repo: repoName, owner: repoOwner }
      );
      return workflows;
    } catch (e) {
      console.error("Error getting workflows", e);
      return [];
    }
  }

  async getUsage(repoOwner, repoName, workflowId, run_id) {
    try {
      const usage = await this._octokit.actions.getWorkflowRunUsage({
        repo: repoName,
        owner: repoOwner,
        workflow_id: workflowId,
        run_id: run_id,
      });
      return usage.data;
    } catch (e) {
      console.error("Error getting usage", e);
      return null;
    }
  }

  async listWorkflowRuns(repoOwner, repoName, workflowId) {
    try {
      const runs = await this._octokit.paginate(
        this._octokit.actions.listWorkflowRuns,
        {
          repo: repoName,
          owner: repoOwner,
          workflow_id: workflowId,
        }
      );

      return runs;
    } catch (e) {
      console.error("Error getting runs", e);
      return null;
    }
  }
}

module.exports = GitHub;


================================================
FILE: index.js
================================================
try {
    const { resolve } = require('path');
    const history = require('connect-history-api-fallback');
    const express = require('express');
    const app = express();
    const server = require('http').createServer(app);

    const configureAPI = require('./configure');

    const { PORT = 8080 } = process.env;

    // API
    configureAPI.before(app);
    configureAPI.after(app, server);

    // UI
    const publicPath = resolve(__dirname, './client/dist');
    const staticConf = { maxAge: '1y', etag: false };

    app.use(history());
    app.use(express.static(publicPath, staticConf));

    app.get('/', function (req, res) {
        res.render(path.join(__dirname + '/client/dist/index.html'))
    });

    // Go
    server.listen(PORT, () => console.log(`Action Dashboard running on port ${PORT}`));
}
catch (e) {
    console.error('Error on startup');
    console.error(e);
}


================================================
FILE: jest.config.js
================================================
/*
 * For a detailed explanation regarding each configuration property, visit:
 * https://jestjs.io/docs/configuration
 */

require("dotenv").config();

module.exports = {
  // All imported modules in your tests should be mocked automatically
  // automock: false,

  // Stop running tests after `n` failures
  // bail: 0,

  // The directory where Jest should store its cached dependency information
  // cacheDirectory: "/private/var/folders/86/97grlb756tlgysggzhl15g9m0000gr/T/jest_e0",

  // Automatically clear mock calls, instances and results before every test
  // clearMocks: false,

  // Indicates whether the coverage information should be collected while executing the test
  // collectCoverage: false,

  // An array of glob patterns indicating a set of files for which coverage information should be collected
  // collectCoverageFrom: undefined,

  // The directory where Jest should output its coverage files
  // coverageDirectory: undefined,

  // An array of regexp pattern strings used to skip coverage collection
  // coveragePathIgnorePatterns: [
  //   "/node_modules/"
  // ],

  // Indicates which provider should be used to instrument code for coverage
  coverageProvider: "v8",

  // A list of reporter names that Jest uses when writing coverage reports
  // coverageReporters: [
  //   "json",
  //   "text",
  //   "lcov",
  //   "clover"
  // ],

  // An object that configures minimum threshold enforcement for coverage results
  // coverageThreshold: undefined,

  // A path to a custom dependency extractor
  // dependencyExtractor: undefined,

  // Make calling deprecated APIs throw helpful error messages
  // errorOnDeprecated: false,

  // Force coverage collection from ignored files using an array of glob patterns
  // forceCoverageMatch: [],

  // A path to a module which exports an async function that is triggered once before all test suites
  // globalSetup: undefined,

  // A path to a module which exports an async function that is triggered once after all test suites
  // globalTeardown: undefined,

  // A set of global variables that need to be available in all test environments
  // globals: {},

  // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
  // maxWorkers: "50%",

  // An array of directory names to be searched recursively up from the requiring module's location
  // moduleDirectories: [
  //   "node_modules"
  // ],

  // An array of file extensions your modules use
  // moduleFileExtensions: [
  //   "js",
  //   "jsx",
  //   "ts",
  //   "tsx",
  //   "json",
  //   "node"
  // ],

  // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
  // moduleNameMapper: {},

  // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
  // modulePathIgnorePatterns: [],

  // Activates notifications for test results
  // notify: false,

  // An enum that specifies notification mode. Requires { notify: true }
  // notifyMode: "failure-change",

  // A preset that is used as a base for Jest's configuration
  // preset: undefined,

  // Run tests from one or more projects
  // projects: undefined,

  // Use this configuration option to add custom reporters to Jest
  // reporters: undefined,

  // Automatically reset mock state before every test
  // resetMocks: false,

  // Reset the module registry before running each individual test
  // resetModules: false,

  // A path to a custom resolver
  // resolver: undefined,

  // Automatically restore mock state and implementation before every test
  // restoreMocks: false,

  // The root directory that Jest should scan for tests and modules within
  // rootDir: undefined,

  // A list of paths to directories that Jest should use to search for files in
  // roots: [
  //   "<rootDir>"
  // ],

  // Allows you to use a custom runner instead of Jest's default test runner
  // runner: "jest-runner",

  // The paths to modules that run some code to configure or set up the testing environment before each test
  // setupFiles: ["/tests/integration/setEnvVars.js"],

  // A list of paths to modules that run some code to configure or set up the testing framework before each test
  // setupFilesAfterEnv: [],

  // The number of seconds after which a test is considered as slow and reported as such in the results.
  // slowTestThreshold: 5,

  // A list of paths to snapshot serializer modules Jest should use for snapshot testing
  // snapshotSerializers: [],

  // The test environment that will be used for testing
  // testEnvironment: "jest-environment-node",

  // Options that will be passed to the testEnvironment
  // testEnvironmentOptions: {},

  // Adds a location field to test results
  // testLocationInResults: false,

  // The glob patterns Jest uses to detect test files
  // testMatch: [
  //   "**/__tests__/**/*.[jt]s?(x)",
  //   "**/?(*.)+(spec|test).[tj]s?(x)"
  // ],

  // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
  // testPathIgnorePatterns: [
  //   "/node_modules/"
  // ],

  // The regexp pattern or array of patterns that Jest uses to detect test files
  // testRegex: [],

  // This option allows the use of a custom results processor
  // testResultsProcessor: undefined,

  // This option allows use of a custom test runner
  // testRunner: "jest-circus/runner",

  // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href
  // testURL: "http://localhost",

  // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout"
  // timers: "real",

  // A map from regular expressions to paths to transformers
  // transform: undefined,

  // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
  // transformIgnorePatterns: [
  //   "/node_modules/",
  //   "\\.pnp\\.[^\\/]+$"
  // ],

  // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
  // unmockedModulePathPatterns: undefined,

  // Indicates whether each individual test should be reported during the run
  // verbose: undefined,

  // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
  // watchPathIgnorePatterns: [],

  // Whether to use watchman for file crawling
  // watchman: true,
};


================================================
FILE: package.json
================================================
{
  "name": "github-action-dashboard",
  "version": "1.6.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test:integration": "DEBUG=action-dashboard,-not_this jest ./tests/integration --silent",
    "test": "DEBUG=action-dashboard,-not_this jest ./tests/unit --silent",
    "serve": "./node_modules/nodemon/bin/nodemon.js index.js --ignore 'client/*.js'  --exec 'npm run lint && node'",
    "lint": "./node_modules/.bin/eslint '**/*.js' --ignore-pattern 'client/dist/' "
  },
  "keywords": [],
  "author": "",
  "license": "MIT",
  "comments": {
    "p-limit": "Stuck on 3.1.0 until we move to ESM"
  },
  "dependencies": {
    "@octokit/auth-app": "^3.6.1",
    "@octokit/plugin-retry": "^3.0.9",
    "@octokit/plugin-throttling": "^3.6.2",
    "@octokit/rest": "^18.12.0",
    "@octokit/webhooks": "^9.24.0",
    "body-parser": "^1.20.0",
    "connect-history-api-fallback": "^1.6.0",
    "dayjs": "^1.11.2",
    "debug": "^4.3.4",
    "dotenv": "^16.0.1",
    "express": "^4.18.1",
    "jest": "^28.1.0",
    "lodash": "^4.17.21",
    "p-limit": "^3.1.0",
    "socket.io": "^4.5.1"
  },
  "devDependencies": {
    "@babel/eslint-parser": "^7.17.0",
    "axios": "^0.27.2",
    "eslint": "^8.16.0"
  }
}


================================================
FILE: routes.js
================================================
const debug = require("debug")("action-dashboard:routes");

class Routes {
  constructor(actions, owner) {
    this._owner = owner;
    this._actions = actions;
  }

  attach(router) {
    router.get("/owner", (req, res, next) => {
      debug(`/owner ${this._owner}`);
      res.send(this._owner);
    });

    router.get("/initialData", (req, res, next) => {
      const initialData = this._actions.getInitialData();
      res.send(initialData);
    });

    router.get("/runs/:owner/:repo/:workflow_id", (req, res, next) => {
      this._actions.refreshWorkflow(
        req.params.owner,
        req.params.repo,
        parseInt(req.params.workflow_id)
      );
      res.send();
    });
  }
}

module.exports = Routes;


================================================
FILE: runstatus.js
================================================
const debug = require("debug")("action-dashboard:runstatus");

class RunStatus {
  start(server) {
    debug("initializing");
    const io = require("socket.io")(server);
    io.on("connection", (client) => {
      debug("connected");
      this._client = client;
    });
  }

  updatedRun(run) {
    if (this._client) {
      debug(`emitting updatedRun: `, run);
      this._client.emit("updatedRun", run);
    }
  }
}

module.exports = RunStatus;


================================================
FILE: tests/integration/github.test.js
================================================
const { TestWatcher } = require("jest");
const GitHub = require("../../github");

// Requires environment variables to be set to run tests
// In local environment this is set out of band via wallaby.conf.js
// In GitHub environment this is set via GitHub secrets

const {
  LOOKBACK_DAYS = 7,
  GITHUB_APPID,
  GITHUB_APP_CLIENTID,
  GITHUB_APP_CLIENTSECRET,
  GITHUB_APP_INSTALLATIONID,
  GITHUB_APP_WEBHOOK_PORT = 8081,
  GITHUB_APP_WEBHOOK_SECRET,
  GITHUB_ORG,
  GITHUB_USERNAME,
} = process.env;

// Handles newlines \n in private key
const GITHUB_APP_PRIVATEKEY = Buffer.from(
  process.env.GITHUB_APP_PRIVATEKEY || "",
  "base64"
).toString("utf-8");

test("GitHub - Environment", () => {
  expect(GITHUB_APP_PRIVATEKEY).toBeTruthy();
  expect(GITHUB_APPID).toBeTruthy();
  expect(GITHUB_APP_CLIENTID).toBeTruthy();
  expect(GITHUB_APP_CLIENTSECRET).toBeTruthy();
  expect(GITHUB_APP_INSTALLATIONID).toBeTruthy();
  expect(GITHUB_USERNAME).toBeTruthy();
});

test("GitHub - listRepos", async () => {
  const gitHub = new GitHub(
    GITHUB_ORG,
    GITHUB_USERNAME,
    GITHUB_APPID,
    GITHUB_APP_PRIVATEKEY,
    GITHUB_APP_CLIENTID,
    GITHUB_APP_CLIENTSECRET,
    GITHUB_APP_INSTALLATIONID
  );

  const repos = await gitHub.listRepos();

  expect(repos).toBeTruthy();
  expect(repos.length > 1).toBeTruthy();
});

test("GitHub - listRepos - Error", async () => {
  const gitHub = new GitHub(
    "XYZ",
    GITHUB_USERNAME,
    GITHUB_APPID,
    GITHUB_APP_PRIVATEKEY,
    GITHUB_APP_CLIENTID,
    GITHUB_APP_CLIENTSECRET,
    GITHUB_APP_INSTALLATIONID
  );

  const repos = await gitHub.listRepos();

  expect(repos).toBeTruthy();
  expect(repos).toHaveLength(0);
});

test("GitHub - listWorkflowsForRepo", async () => {
  const gitHub = new GitHub(
    GITHUB_ORG,
    GITHUB_USERNAME,
    GITHUB_APPID,
    GITHUB_APP_PRIVATEKEY,
    GITHUB_APP_CLIENTID,
    GITHUB_APP_CLIENTSECRET,
    GITHUB_APP_INSTALLATIONID
  );

  const workflows = await gitHub.listWorkflowsForRepo(
    "github-action-dashboard",
    "chriskinsman"
  );

  expect(workflows).toBeTruthy();
  expect(workflows.length > 0).toBeTruthy();
});

test("GitHub - listWorkflowsForRepo Error", async () => {
  const gitHub = new GitHub(
    GITHUB_ORG,
    GITHUB_USERNAME,
    GITHUB_APPID,
    GITHUB_APP_PRIVATEKEY,
    GITHUB_APP_CLIENTID,
    GITHUB_APP_CLIENTSECRET,
    GITHUB_APP_INSTALLATIONID
  );

  const workflows = await gitHub.listWorkflowsForRepo(
    "github-action-dashboard-missing",
    "chriskinsman"
  );

  expect(workflows).toBeTruthy();
  expect(workflows).toHaveLength(0);
});

test("GitHub - listWorkflowRuns", async () => {
  const gitHub = new GitHub(
    GITHUB_ORG,
    GITHUB_USERNAME,
    GITHUB_APPID,
    GITHUB_APP_PRIVATEKEY,
    GITHUB_APP_CLIENTID,
    GITHUB_APP_CLIENTSECRET,
    GITHUB_APP_INSTALLATIONID
  );

  const runs = await gitHub.listWorkflowRuns(
    "chriskinsman",
    "github-action-dashboard",
    "5777275"
  );

  expect(runs).toBeTruthy();
  expect(runs.length > 0).toBeTruthy();
});

test("GitHub - listWorkflowRuns Error", async () => {
  const gitHub = new GitHub(
    GITHUB_ORG,
    GITHUB_USERNAME,
    GITHUB_APPID,
    GITHUB_APP_PRIVATEKEY,
    GITHUB_APP_CLIENTID,
    GITHUB_APP_CLIENTSECRET,
    GITHUB_APP_INSTALLATIONID
  );

  const runs = await gitHub.listWorkflowRuns(
    "chriskinsman",
    "github-action-dashboard",
    "23"
  );

  expect(runs).toBeFalsy();
});

test("GitHub - getUsage", async () => {
  const gitHub = new GitHub(
    GITHUB_ORG,
    GITHUB_USERNAME,
    GITHUB_APPID,
    GITHUB_APP_PRIVATEKEY,
    GITHUB_APP_CLIENTID,
    GITHUB_APP_CLIENTSECRET,
    GITHUB_APP_INSTALLATIONID
  );

  const usage = await gitHub.getUsage(
    "chriskinsman",
    "github-action-dashboard",
    "5777275",
    "1511883909"
  );

  expect(usage).toBeTruthy();
  expect(usage.run_duration_ms).toBeTruthy();
});

test("GitHub - getUsage Error", async () => {
  const gitHub = new GitHub(
    GITHUB_ORG,
    GITHUB_USERNAME,
    GITHUB_APPID,
    GITHUB_APP_PRIVATEKEY,
    GITHUB_APP_CLIENTID,
    GITHUB_APP_CLIENTSECRET,
    GITHUB_APP_INSTALLATIONID
  );

  const usage = await gitHub.getUsage(
    "chriskinsman",
    "github-action-dashboard",
    "5777275",
    "12"
  );

  expect(usage).toBeFalsy();
});


================================================
FILE: tests/unit/actions.test.js
================================================
const Actions = require("../../actions");

const mockData = require("./mock_data");

afterEach(() => {
  jest.restoreAllMocks();
  jest.useRealTimers();
});

test("Actions - Start", () => {
  jest.useFakeTimers();
  const gitHub = require("../../github");
  const actions = new Actions(gitHub);
  const refreshRuns = jest
    .spyOn(actions, "refreshRuns")
    .mockImplementation(() => {});

  actions.start();
  expect(refreshRuns.mock.calls.length).toBe(1);

  jest.advanceTimersByTime(1000 * 60 * 16);
  expect(refreshRuns.mock.calls.length).toBe(2);
});

test("Actions - getMostRecentRuns Empty", async () => {
  jest.mock("../../github");
  const GitHub = require("../../github");
  const listWorkflowRuns = jest.fn(async () => {
    return [];
  });
  GitHub.mockImplementation(() => {
    return {
      listWorkflowRuns: listWorkflowRuns,
    };
  });

  const gitHub = new GitHub();
  const actions = new Actions(gitHub, null, 7);
  const runs = await actions.getMostRecentRuns(
    "ChrisKinsman",
    "github-action-dashboard",
    ""
  );

  expect(runs).toBeTruthy();
  expect(runs).toHaveLength(0);
  expect(listWorkflowRuns.mock.calls).toHaveLength(1);
});

test("Actions - getMostRecentRuns Error", async () => {
  jest.mock("../../github");
  const GitHub = require("../../github");
  const listWorkflowRuns = jest.fn(async () => {
    throw new Error("Foo");
  });
  GitHub.mockImplementation(() => {
    return {
      listWorkflowRuns,
    };
  });

  const gitHub = new GitHub();
  const actions = new Actions(gitHub, null, 7);

  const runs = await actions.getMostRecentRuns(
    "ChrisKinsman",
    "github-action-dashboard",
    ""
  );

  expect(runs).toBeTruthy();
  expect(runs).toHaveLength(0);
});

test("Actions - getMostRecentRuns With Data", async () => {
  jest.mock("../../github");
  const GitHub = require("../../github");
  const listWorkflowRuns = jest.fn(async () => {
    const mockRuns = [...mockData.runs];
    return mockRuns;
  });
  const getUsage = jest.fn(async () => {
    return { run_duration_ms: 10000 };
  });
  GitHub.mockImplementation(() => {
    return {
      listWorkflowRuns,
      getUsage,
    };
  });

  const gitHub = new GitHub();

  // Long lookback for our test data
  const actions = new Actions(gitHub, null, 600);
  const runs = await actions.getMostRecentRuns(
    "ChrisKinsman",
    "github-action-dashboard",
    ""
  );
  console.dir(runs);
  expect(runs).toBeTruthy();
  expect(runs.length > 0).toBeTruthy();
});

test("Actions - getInitialData", async () => {
  const gitHub = require("../../github");
  const actions = new Actions(gitHub);
  const refreshRuns = jest
    .spyOn(actions, "refreshRuns")
    .mockImplementation(() => {});

  actions.getInitialData();
  expect(refreshRuns.mock.calls.length).toBe(1);
});

test("Actions - refreshWorkflow", async () => {
  const gitHub = require("../../github");
  const actions = new Actions(gitHub);
  const getMostRecentRuns = jest
    .spyOn(actions, "getMostRecentRuns")
    .mockImplementation(async () => {
      return [];
    });
  const mergeRuns = jest.spyOn(actions, "mergeRuns").mockImplementation(() => {
    return;
  });

  await actions.refreshWorkflow();

  expect(getMostRecentRuns.mock.calls.length).toBe(1);
  expect(mergeRuns.mock.calls.length).toBe(1);
});

test("Actions - mergeRuns", () => {
  const mockRuns = [...mockData.runs];
  const gitHub = require("../../github");
  const RunStatus = require("../../runstatus");
  const runStatus = new RunStatus();
  const updatedRun = jest
    .spyOn(runStatus, "updatedRun")
    .mockImplementation(() => {
      return;
    });

  const actions = new Actions(gitHub, runStatus);

  actions.mergeRuns(mockRuns);

  expect(updatedRun.mock.calls).toHaveLength(mockRuns.length);
});

test("Actions - refreshRuns", async () => {
  jest.mock("../../github");
  const GitHub = require("../../github");
  const listRepos = jest.fn(async () => {
    return [...mockData.repos];
  });
  const listWorkflowsForRepo = jest.fn(async () => {
    return [...mockData.workflows];
  });
  const listWorkflowRuns = jest.fn(async () => {
    return [...mockData.runs];
  });

  GitHub.mockImplementation(() => {
    return {
      listRepos,
      listWorkflowsForRepo,
      listWorkflowRuns,
    };
  });

  const gitHub = new GitHub();

  const actions = new Actions(gitHub);
  await actions.refreshRuns();

  expect(listRepos.mock.calls).toHaveLength(1);
  expect(listWorkflowsForRepo.mock.calls).toHaveLength(1);
  expect(listWorkflowRuns.mock.calls.length > 0).toBeTruthy();
});

test("Actions - refreshRuns Error", async () => {
  // Setup
  jest.mock("../../github");
  const GitHub = require("../../github");
  const listRepos = jest.fn(async () => {
    throw new Error("foo");
  });
  const listWorkflowsForRepo = jest.fn(async () => {
    return [...mockData.workflows];
  });
  const listWorkflowRuns = jest.fn(async () => {
    return [...mockData.runs];
  });

  GitHub.mockImplementation(() => {
    return {
      listRepos,
      listWorkflowsForRepo,
      listWorkflowRuns,
    };
  });

  const gitHub = new GitHub();
  const actions = new Actions(gitHub);

  // Test
  await actions.refreshRuns();

  // Assertions
  expect(listRepos.mock.calls).toHaveLength(1);
  expect(listWorkflowsForRepo.mock.calls).toHaveLength(0);
  expect(listWorkflowRuns.mock.calls).toHaveLength(0);
});


================================================
FILE: tests/unit/mock_data.js
================================================
module.exports = {
  repos: [
    {
      name: "github-action-dashboard",
      owner: {
        login: "chriskinsman",
      },
    },
  ],
  workflows: [
    {
      id: 5777275,
      node_id: "MDg6V29ya2Zsb3c1Nzc3Mjc1",
      name: "ci",
      path: ".github/workflows/ci.yaml",
      state: "active",
      created_at: "2021-02-12T20:43:01.000Z",
      updated_at: "2021-02-12T22:21:23.000Z",
      url: "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/workflows/5777275",
      html_url:
        "https://github.com/chriskinsman/github-action-dashboard/blob/main/.github/workflows/ci.yaml",
      badge_url:
        "https://github.com/chriskinsman/github-action-dashboard/workflows/ci/badge.svg",
    },
  ],
  runs: [
    {
      id: 1511883909,
      name: "ci",
      node_id: "WFR_kwLOFCwDGs5aHYSF",
      head_branch: "main",
      head_sha: "62e3da7b6ecfb43cfff9ba03922dd45dbebd44d7",
      run_number: 89,
      event: "push",
      status: "completed",
      conclusion: "success",
      workflow_id: 5777275,
      check_suite_id: 4483441607,
      check_suite_node_id: "CS_kwDOFCwDGs8AAAABCzvjxw",
      url: "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511883909",
      html_url:
        "https://github.com/chriskinsman/github-action-dashboard/actions/runs/1511883909",
      pull_requests: [],
      created_at: "2021-11-28T04:20:51Z",
      updated_at: "2021-11-28T04:31:54Z",
      run_attempt: 1,
      run_started_at: "2021-11-28T04:20:51Z",
      jobs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511883909/jobs",
      logs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511883909/logs",
      check_suite_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/check-suites/4483441607",
      artifacts_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511883909/artifacts",
      cancel_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511883909/cancel",
      rerun_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511883909/rerun",
      previous_attempt_url: null,
      workflow_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/workflows/5777275",
      head_commit: {
        id: "62e3da7b6ecfb43cfff9ba03922dd45dbebd44d7",
        tree_id: "c2928a14a5b001f7e14ab64fdfc3888f9de5c783",
        message: "Remove debug from dockerfile",
        timestamp: "2021-11-28T04:20:46Z",
        author: { name: "Chris Kinsman", email: "chris@kinsman.net" },
        committer: { name: "Chris Kinsman", email: "chris@kinsman.net" },
      },
      repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
      head_repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
    },
    {
      id: 1511882742,
      name: "ci",
      node_id: "WFR_kwLOFCwDGs5aHX_2",
      head_branch: "main",
      head_sha: "a871b8675abe396fa4c5d697c57acfd5e63762f6",
      run_number: 88,
      event: "push",
      status: "completed",
      conclusion: "success",
      workflow_id: 5777275,
      check_suite_id: 4483439479,
      check_suite_node_id: "CS_kwDOFCwDGs8AAAABCzvbdw",
      url: "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511882742",
      html_url:
        "https://github.com/chriskinsman/github-action-dashboard/actions/runs/1511882742",
      pull_requests: [],
      created_at: "2021-11-28T04:20:05Z",
      updated_at: "2021-11-28T04:34:37Z",
      run_attempt: 1,
      run_started_at: "2021-11-28T04:20:05Z",
      jobs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511882742/jobs",
      logs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511882742/logs",
      check_suite_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/check-suites/4483439479",
      artifacts_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511882742/artifacts",
      cancel_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511882742/cancel",
      rerun_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511882742/rerun",
      previous_attempt_url: null,
      workflow_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/workflows/5777275",
      head_commit: {
        id: "a871b8675abe396fa4c5d697c57acfd5e63762f6",
        tree_id: "779499b038109d7bab763bf3dbabb1fcb7d82ff6",
        message:
          "Update packages (#16)\n" +
          "\n" +
          "* Update to node16\r\n" +
          "* update packages\r\n" +
          "* fix middleware\r\n" +
          "* Update dockerfile to python3\r\n" +
          "* Prevent routes/webhooks from loading during build",
        timestamp: "2021-11-28T04:20:03Z",
        author: {
          name: "Chris Kinsman",
          email: "chriskinsman@users.noreply.github.com",
        },
        committer: { name: "GitHub", email: "noreply@github.com" },
      },
      repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
      head_repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
    },
    {
      id: 1511879655,
      name: "ci",
      node_id: "WFR_kwLOFCwDGs5aHXPn",
      head_branch: "update-packages",
      head_sha: "ab75d2394eb310603ae63d02644fcb88d3a972ca",
      run_number: 87,
      event: "pull_request",
      status: "queued",
      conclusion: "success",
      workflow_id: 5777275,
      check_suite_id: 4483434347,
      check_suite_node_id: "CS_kwDOFCwDGs8AAAABCzvHaw",
      url: "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511879655",
      html_url:
        "https://github.com/chriskinsman/github-action-dashboard/actions/runs/1511879655",
      pull_requests: [],
      created_at: "2021-11-28T04:18:04Z",
      updated_at: "2021-11-28T04:29:15Z",
      run_attempt: 1,
      run_started_at: "2021-11-28T04:18:04Z",
      jobs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511879655/jobs",
      logs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511879655/logs",
      check_suite_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/check-suites/4483434347",
      artifacts_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511879655/artifacts",
      cancel_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511879655/cancel",
      rerun_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511879655/rerun",
      previous_attempt_url: null,
      workflow_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/workflows/5777275",
      head_commit: {
        id: "ab75d2394eb310603ae63d02644fcb88d3a972ca",
        tree_id: "779499b038109d7bab763bf3dbabb1fcb7d82ff6",
        message: "Conditionally load",
        timestamp: "2021-11-28T03:56:21Z",
        author: { name: "Chris Kinsman", email: "chris@kinsman.net" },
        committer: { name: "Chris Kinsman", email: "chris@kinsman.net" },
      },
      repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
      head_repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
    },
    {
      id: 1511843912,
      name: "ci",
      node_id: "WFR_kwLOFCwDGs5aHOhI",
      head_branch: "update-packages",
      head_sha: "ab75d2394eb310603ae63d02644fcb88d3a972ca",
      run_number: 86,
      event: "push",
      status: "completed",
      conclusion: "success",
      workflow_id: 5777275,
      check_suite_id: 4483373432,
      check_suite_node_id: "CS_kwDOFCwDGs8AAAABCzrZeA",
      url: "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511843912",
      html_url:
        "https://github.com/chriskinsman/github-action-dashboard/actions/runs/1511843912",
      pull_requests: [],
      created_at: "2021-11-28T03:56:26Z",
      updated_at: "2021-11-28T04:09:28Z",
      run_attempt: 1,
      run_started_at: "2021-11-28T03:56:26Z",
      jobs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511843912/jobs",
      logs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511843912/logs",
      check_suite_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/check-suites/4483373432",
      artifacts_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511843912/artifacts",
      cancel_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511843912/cancel",
      rerun_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511843912/rerun",
      previous_attempt_url: null,
      workflow_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/workflows/5777275",
      head_commit: {
        id: "ab75d2394eb310603ae63d02644fcb88d3a972ca",
        tree_id: "779499b038109d7bab763bf3dbabb1fcb7d82ff6",
        message: "Conditionally load",
        timestamp: "2021-11-28T03:56:21Z",
        author: { name: "Chris Kinsman", email: "chris@kinsman.net" },
        committer: { name: "Chris Kinsman", email: "chris@kinsman.net" },
      },
      repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
      head_repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
    },
    {
      id: 1511839387,
      name: "ci",
      node_id: "WFR_kwLOFCwDGs5aHNab",
      head_branch: "update-packages",
      head_sha: "984f69a9448a700689554cf64083113e17aa0984",
      run_number: 85,
      event: "push",
      status: "completed",
      conclusion: "failure",
      workflow_id: 5777275,
      check_suite_id: 4483365240,
      check_suite_node_id: "CS_kwDOFCwDGs8AAAABCzq5eA",
      url: "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511839387",
      html_url:
        "https://github.com/chriskinsman/github-action-dashboard/actions/runs/1511839387",
      pull_requests: [],
      created_at: "2021-11-28T03:52:56Z",
      updated_at: "2021-11-28T03:54:18Z",
      run_attempt: 1,
      run_started_at: "2021-11-28T03:52:56Z",
      jobs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511839387/jobs",
      logs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511839387/logs",
      check_suite_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/check-suites/4483365240",
      artifacts_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511839387/artifacts",
      cancel_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511839387/cancel",
      rerun_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511839387/rerun",
      previous_attempt_url: null,
      workflow_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/workflows/5777275",
      head_commit: {
        id: "984f69a9448a700689554cf64083113e17aa0984",
        tree_id: "7afee908ca883dfb98d77807f6802cda70600a06",
        message: "More debugging",
        timestamp: "2021-11-28T03:52:44Z",
        author: { name: "Chris Kinsman", email: "chris@kinsman.net" },
        committer: { name: "Chris Kinsman", email: "chris@kinsman.net" },
      },
      repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
      head_repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
    },
    {
      id: 1511836026,
      name: "ci",
      node_id: "WFR_kwLOFCwDGs5aHMl6",
      head_branch: "update-packages",
      head_sha: "1f3a80b423d61919354f5d56751f9b3b717e945f",
      run_number: 84,
      event: "push",
      status: "completed",
      conclusion: "failure",
      workflow_id: 5777275,
      check_suite_id: 4483359288,
      check_suite_node_id: "CS_kwDOFCwDGs8AAAABCzqiOA",
      url: "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511836026",
      html_url:
        "https://github.com/chriskinsman/github-action-dashboard/actions/runs/1511836026",
      pull_requests: [],
      created_at: "2021-11-28T03:50:11Z",
      updated_at: "2021-11-28T03:51:31Z",
      run_attempt: 1,
      run_started_at: "2021-11-28T03:50:11Z",
      jobs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511836026/jobs",
      logs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511836026/logs",
      check_suite_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/check-suites/4483359288",
      artifacts_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511836026/artifacts",
      cancel_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511836026/cancel",
      rerun_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511836026/rerun",
      previous_attempt_url: null,
      workflow_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/workflows/5777275",
      head_commit: {
        id: "1f3a80b423d61919354f5d56751f9b3b717e945f",
        tree_id: "bb1df679f43eda911ae6f64f2de725414982d9ae",
        message: "Debug build",
        timestamp: "2021-11-28T03:49:57Z",
        author: { name: "Chris Kinsman", email: "chris@kinsman.net" },
        committer: { name: "Chris Kinsman", email: "chris@kinsman.net" },
      },
      repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
      head_repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
    },
    {
      id: 1511831040,
      name: "ci",
      node_id: "WFR_kwLOFCwDGs5aHLYA",
      head_branch: "update-packages",
      head_sha: "8a7e08931c893efc6e92cf98f86cdd7323bc551c",
      run_number: 83,
      event: "push",
      status: "completed",
      conclusion: "failure",
      workflow_id: 5777275,
      check_suite_id: 4483350691,
      check_suite_node_id: "CS_kwDOFCwDGs8AAAABCzqAow",
      url: "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511831040",
      html_url:
        "https://github.com/chriskinsman/github-action-dashboard/actions/runs/1511831040",
      pull_requests: [],
      created_at: "2021-11-28T03:46:30Z",
      updated_at: "2021-11-28T03:48:02Z",
      run_attempt: 1,
      run_started_at: "2021-11-28T03:46:30Z",
      jobs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511831040/jobs",
      logs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511831040/logs",
      check_suite_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/check-suites/4483350691",
      artifacts_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511831040/artifacts",
      cancel_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511831040/cancel",
      rerun_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511831040/rerun",
      previous_attempt_url: null,
      workflow_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/workflows/5777275",
      head_commit: {
        id: "8a7e08931c893efc6e92cf98f86cdd7323bc551c",
        tree_id: "0ab88085be5f2876df66de3b212e606d726a2a6d",
        message: "Conditionally load webhooks",
        timestamp: "2021-11-28T03:46:13Z",
        author: { name: "Chris Kinsman", email: "chris@kinsman.net" },
        committer: { name: "Chris Kinsman", email: "chris@kinsman.net" },
      },
      repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
      head_repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
    },
    {
      id: 1511521089,
      name: "ci",
      node_id: "WFR_kwLOFCwDGs5aF_tB",
      head_branch: "update-packages",
      head_sha: "e8de665a95c0dd36c807bcec8c81acd8854716fb",
      run_number: 82,
      event: "push",
      status: "completed",
      conclusion: "failure",
      workflow_id: 5777275,
      check_suite_id: 4482822200,
      check_suite_node_id: "CS_kwDOFCwDGs8AAAABCzJwOA",
      url: "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511521089",
      html_url:
        "https://github.com/chriskinsman/github-action-dashboard/actions/runs/1511521089",
      pull_requests: [],
      created_at: "2021-11-28T00:44:05Z",
      updated_at: "2021-11-28T00:45:37Z",
      run_attempt: 1,
      run_started_at: "2021-11-28T00:44:05Z",
      jobs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511521089/jobs",
      logs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511521089/logs",
      check_suite_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/check-suites/4482822200",
      artifacts_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511521089/artifacts",
      cancel_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511521089/cancel",
      rerun_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511521089/rerun",
      previous_attempt_url: null,
      workflow_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/workflows/5777275",
      head_commit: {
        id: "e8de665a95c0dd36c807bcec8c81acd8854716fb",
        tree_id: "0ba7f0bcd8553d67166c1f898e99265618eedf8d",
        message: "Alter build test",
        timestamp: "2021-11-28T00:43:59Z",
        author: { name: "Chris Kinsman", email: "chris@kinsman.net" },
        committer: { name: "Chris Kinsman", email: "chris@kinsman.net" },
      },
      repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
      head_repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
    },
    {
      id: 1511513558,
      name: "ci",
      node_id: "WFR_kwLOFCwDGs5aF93W",
      head_branch: "update-packages",
      head_sha: "7e154608aaf57b651655b2d7868b721e71f1fa12",
      run_number: 81,
      event: "push",
      status: "completed",
      conclusion: "failure",
      workflow_id: 5777275,
      check_suite_id: 4482809931,
      check_suite_node_id: "CS_kwDOFCwDGs8AAAABCzJASw",
      url: "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511513558",
      html_url:
        "https://github.com/chriskinsman/github-action-dashboard/actions/runs/1511513558",
      pull_requests: [],
      created_at: "2021-11-28T00:40:34Z",
      updated_at: "2021-11-28T00:42:30Z",
      run_attempt: 1,
      run_started_at: "2021-11-28T00:40:34Z",
      jobs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511513558/jobs",
      logs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511513558/logs",
      check_suite_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/check-suites/4482809931",
      artifacts_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511513558/artifacts",
      cancel_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511513558/cancel",
      rerun_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511513558/rerun",
      previous_attempt_url: null,
      workflow_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/workflows/5777275",
      head_commit: {
        id: "7e154608aaf57b651655b2d7868b721e71f1fa12",
        tree_id: "7ed192a62ee6d8520b20e1d0ccdf2a71a6f164e6",
        message: "Prevent routes from loading during build",
        timestamp: "2021-11-28T00:40:28Z",
        author: { name: "Chris Kinsman", email: "chris@kinsman.net" },
        committer: { name: "Chris Kinsman", email: "chris@kinsman.net" },
      },
      repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
      head_repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
    },
    {
      id: 1511488356,
      name: "ci",
      node_id: "WFR_kwLOFCwDGs5aF3tk",
      head_branch: "update-packages",
      head_sha: "692f92439ca300e86c6126de2cd8fdf3589ac884",
      run_number: 80,
      event: "push",
      status: "completed",
      conclusion: "failure",
      workflow_id: 5777275,
      check_suite_id: 4482768032,
      check_suite_node_id: "CS_kwDOFCwDGs8AAAABCzGcoA",
      url: "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511488356",
      html_url:
        "https://github.com/chriskinsman/github-action-dashboard/actions/runs/1511488356",
      pull_requests: [],
      created_at: "2021-11-28T00:29:04Z",
      updated_at: "2021-11-28T00:30:35Z",
      run_attempt: 1,
      run_started_at: "2021-11-28T00:29:04Z",
      jobs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511488356/jobs",
      logs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511488356/logs",
      check_suite_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/check-suites/4482768032",
      artifacts_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511488356/artifacts",
      cancel_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511488356/cancel",
      rerun_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511488356/rerun",
      previous_attempt_url: null,
      workflow_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/workflows/5777275",
      head_commit: {
        id: "692f92439ca300e86c6126de2cd8fdf3589ac884",
        tree_id: "ceb80d1e23b4c9631c97e9d04458dffefaa800d1",
        message: "Update to python3",
        timestamp: "2021-11-28T00:28:57Z",
        author: { name: "Chris Kinsman", email: "chris@kinsman.net" },
        committer: { name: "Chris Kinsman", email: "chris@kinsman.net" },
      },
      repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
      head_repository: {
        id: 338428698,
        node_id: "MDEwOlJlcG9zaXRvcnkzMzg0Mjg2OTg=",
        name: "github-action-dashboard",
        full_name: "chriskinsman/github-action-dashboard",
        private: false,
        owner: {
          login: "chriskinsman",
          id: 1522018,
          node_id: "MDQ6VXNlcjE1MjIwMTg=",
          avatar_url: "https://avatars.githubusercontent.com/u/1522018?v=4",
          gravatar_id: "",
          url: "https://api.github.com/users/chriskinsman",
          html_url: "https://github.com/chriskinsman",
          followers_url: "https://api.github.com/users/chriskinsman/followers",
          following_url:
            "https://api.github.com/users/chriskinsman/following{/other_user}",
          gists_url:
            "https://api.github.com/users/chriskinsman/gists{/gist_id}",
          starred_url:
            "https://api.github.com/users/chriskinsman/starred{/owner}{/repo}",
          subscriptions_url:
            "https://api.github.com/users/chriskinsman/subscriptions",
          organizations_url: "https://api.github.com/users/chriskinsman/orgs",
          repos_url: "https://api.github.com/users/chriskinsman/repos",
          events_url:
            "https://api.github.com/users/chriskinsman/events{/privacy}",
          received_events_url:
            "https://api.github.com/users/chriskinsman/received_events",
          type: "User",
          site_admin: false,
        },
        html_url: "https://github.com/chriskinsman/github-action-dashboard",
        description:
          "A dashboard to keep track of the status of your GitHub Actions",
        fork: false,
        url: "https://api.github.com/repos/chriskinsman/github-action-dashboard",
        forks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/forks",
        keys_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/keys{/key_id}",
        collaborators_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/collaborators{/collaborator}",
        teams_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/teams",
        hooks_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/hooks",
        issue_events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/events{/number}",
        events_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/events",
        assignees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/assignees{/user}",
        branches_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/branches{/branch}",
        tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/tags",
        blobs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/blobs{/sha}",
        git_tags_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/tags{/sha}",
        git_refs_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/refs{/sha}",
        trees_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/trees{/sha}",
        statuses_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/statuses/{sha}",
        languages_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/languages",
        stargazers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/stargazers",
        contributors_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contributors",
        subscribers_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscribers",
        subscription_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/subscription",
        commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/commits{/sha}",
        git_commits_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/git/commits{/sha}",
        comments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/comments{/number}",
        issue_comment_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues/comments{/number}",
        contents_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/contents/{+path}",
        compare_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/compare/{base}...{head}",
        merges_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/merges",
        archive_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/{archive_format}{/ref}",
        downloads_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/downloads",
        issues_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/issues{/number}",
        pulls_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/pulls{/number}",
        milestones_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/milestones{/number}",
        notifications_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/notifications{?since,all,participating}",
        labels_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/labels{/name}",
        releases_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/releases{/id}",
        deployments_url:
          "https://api.github.com/repos/chriskinsman/github-action-dashboard/deployments",
      },
    },
    {
      id: 1511482134,
      name: "ci",
      node_id: "WFR_kwLOFCwDGs5aF2MW",
      head_branch: "update-packages",
      head_sha: "92ae6807abef383e549e317437f41b004037114f",
      run_number: 79,
      event: "push",
      status: "completed",
      conclusion: "failure",
      workflow_id: 5777275,
      check_suite_id: 4482757259,
      check_suite_node_id: "CS_kwDOFCwDGs8AAAABCzFyiw",
      url: "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511482134",
      html_url:
        "https://github.com/chriskinsman/github-action-dashboard/actions/runs/1511482134",
      pull_requests: [],
      created_at: "2021-11-28T00:25:55Z",
      updated_at: "2021-11-28T00:26:32Z",
      run_attempt: 1,
      run_started_at: "2021-11-28T00:25:55Z",
      jobs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511482134/jobs",
      logs_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511482134/logs",
      check_suite_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/check-suites/4482757259",
      artifacts_url:
        "https://api.github.com/repos/chriskinsman/github-action-dashboard/actions/runs/1511482134/artifacts",
      cancel_url:
        "https://api.githu
Download .txt
gitextract_680p5qqh/

├── .dockerignore
├── .eslintrc.js
├── .github/
│   └── workflows/
│       └── ci.yaml
├── .gitignore
├── .nvmrc
├── Dockerfile
├── LICENSE
├── README.md
├── actions.js
├── client/
│   ├── .gitignore
│   ├── babel.config.js
│   ├── jsconfig.json
│   ├── package.json
│   ├── public/
│   │   ├── index.html
│   │   └── robots.txt
│   ├── src/
│   │   ├── App.vue
│   │   ├── components/
│   │   │   └── actiondashboard.vue
│   │   ├── main.js
│   │   └── plugins/
│   │       ├── vue-socket-io-extended.js
│   │       └── vuetify.js
│   └── vue.config.js
├── configure.js
├── getinstallationid.js
├── github.js
├── index.js
├── jest.config.js
├── package.json
├── routes.js
├── runstatus.js
├── tests/
│   ├── integration/
│   │   └── github.test.js
│   └── unit/
│       ├── actions.test.js
│       ├── mock_data.js
│       ├── runstatus.test.js
│       └── webooks.test.js
└── webhooks.js
Download .txt
SYMBOL INDEX (26 symbols across 8 files)

FILE: actions.js
  class Actions (line 6) | class Actions {
    method constructor (line 7) | constructor(gitHub, runStatus, lookbackDays) {
    method start (line 16) | start() {
    method getMostRecentRuns (line 26) | async getMostRecentRuns(repoOwner, repoName, workflowId) {
    method mergeRuns (line 109) | mergeRuns(runs) {
    method refreshWorkflow (line 165) | async refreshWorkflow(repoOwner, repoName, workflowId) {
    method getInitialData (line 170) | getInitialData() {

FILE: client/src/plugins/vue-socket-io-extended.js
  method connect (line 11) | connect() {

FILE: configure.js
  constant GITHUB_APP_PRIVATEKEY (line 40) | const GITHUB_APP_PRIVATEKEY = Buffer.from(

FILE: github.js
  class GitHub (line 7) | class GitHub {
    method constructor (line 8) | constructor(
    method listRepos (line 64) | async listRepos() {
    method listWorkflowsForRepo (line 74) | async listWorkflowsForRepo(repoName, repoOwner) {
    method getUsage (line 87) | async getUsage(repoOwner, repoName, workflowId, run_id) {
    method listWorkflowRuns (line 102) | async listWorkflowRuns(repoOwner, repoName, workflowId) {

FILE: routes.js
  class Routes (line 3) | class Routes {
    method constructor (line 4) | constructor(actions, owner) {
    method attach (line 9) | attach(router) {

FILE: runstatus.js
  class RunStatus (line 3) | class RunStatus {
    method start (line 4) | start(server) {
    method updatedRun (line 13) | updatedRun(run) {

FILE: tests/integration/github.test.js
  constant GITHUB_APP_PRIVATEKEY (line 21) | const GITHUB_APP_PRIVATEKEY = Buffer.from(

FILE: webhooks.js
  class WebHooks (line 5) | class WebHooks {
    method constructor (line 6) | constructor(
    method start (line 41) | start() {
    method stop (line 90) | stop() {
Condensed preview — 35 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (524K chars).
[
  {
    "path": ".dockerignore",
    "chars": 195,
    "preview": "*.crt\n*.key\n.dockerignore\n.git\n.gitignore\n.idea\n.jshintrc\ncommit.sha\n# dist\n# dist/*\nDockerfile\n#node_modules/*\nREADME.m"
  },
  {
    "path": ".eslintrc.js",
    "chars": 221,
    "preview": "module.exports = {\n  env: {\n    browser: true,\n    es2020: true,\n  },\n  parser: \"@babel/eslint-parser\",\n  parserOptions:"
  },
  {
    "path": ".github/workflows/ci.yaml",
    "chars": 2343,
    "preview": "name: ci\non:\n  workflow_dispatch:\n  push:\n  # pull_request:\n  #   branches: main\njobs:\n  build:\n    runs-on: ubuntu-late"
  },
  {
    "path": ".gitignore",
    "chars": 265,
    "preview": ".DS_Store\nnode_modules\n/dist\n/client/dist\n\n# local env files\n.env\n.env.local\n.env.*.local\n\n# Log files\nnpm-debug.log*\nya"
  },
  {
    "path": ".nvmrc",
    "chars": 8,
    "preview": "v16.13.1"
  },
  {
    "path": "Dockerfile",
    "chars": 694,
    "preview": "FROM node:16-alpine as base\nLABEL org.opencontainers.image.source=https://github.com/ChrisKinsman/github-action-dashboar"
  },
  {
    "path": "LICENSE",
    "chars": 1102,
    "preview": "(The MIT License)\n\nCopyright (c) 2009-2014 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of ch"
  },
  {
    "path": "README.md",
    "chars": 7513,
    "preview": "# GitHub Action Dashboard - No Longer Supported\n\nMy team is no longer using this for monitoring our GitHub actions.  Fee"
  },
  {
    "path": "actions.js",
    "chars": 5190,
    "preview": "const debug = require(\"debug\")(\"action-dashboard:actions\");\nconst _ = require(\"lodash\");\nconst dayjs = require(\"dayjs\");"
  },
  {
    "path": "client/.gitignore",
    "chars": 231,
    "preview": ".DS_Store\nnode_modules\n/dist\n\n\n# local env files\n.env.local\n.env.*.local\n\n# Log files\nnpm-debug.log*\nyarn-debug.log*\nyar"
  },
  {
    "path": "client/babel.config.js",
    "chars": 73,
    "preview": "module.exports = {\n  presets: [\n    '@vue/cli-plugin-babel/preset'\n  ]\n}\n"
  },
  {
    "path": "client/jsconfig.json",
    "chars": 208,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"es2015\",\n    \"module\": \"esnext\",\n    \"baseUrl\": \"./\",\n    \"paths\": {\n      \"@/*\""
  },
  {
    "path": "client/package.json",
    "chars": 1192,
    "preview": "{\n  \"name\": \"client\",\n  \"version\": \"1.6.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"serve\": \"vue-cli-service serve\",\n    "
  },
  {
    "path": "client/public/index.html",
    "chars": 884,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
  },
  {
    "path": "client/public/robots.txt",
    "chars": 25,
    "preview": "User-agent: *\nDisallow: /"
  },
  {
    "path": "client/src/App.vue",
    "chars": 830,
    "preview": "<template>\n    <v-app>\n        <v-app-bar app color=\"primary\" dark>\n            <v-app-bar-title>{{ owner }} Action Dash"
  },
  {
    "path": "client/src/components/actiondashboard.vue",
    "chars": 5971,
    "preview": "<template>\n    <v-container :fluid=\"true\">\n        <v-data-table\n            :headers=\"headers\"\n            :items=\"runs"
  },
  {
    "path": "client/src/main.js",
    "chars": 278,
    "preview": "import Vue from 'vue'\nimport App from './App.vue'\nimport vuetify from './plugins/vuetify';\nimport vueSocketIoExtended fr"
  },
  {
    "path": "client/src/plugins/vue-socket-io-extended.js",
    "chars": 286,
    "preview": "import Vue from 'vue';\nimport VueSocketIOExt from 'vue-socket.io-extended';\nimport { io } from 'socket.io-client';\n\ncons"
  },
  {
    "path": "client/src/plugins/vuetify.js",
    "chars": 121,
    "preview": "import Vue from 'vue';\nimport Vuetify from 'vuetify/lib/framework';\n\nVue.use(Vuetify);\n\nexport default new Vuetify({\n});"
  },
  {
    "path": "client/vue.config.js",
    "chars": 421,
    "preview": "const configureAPI = require('../configure');\n\nmodule.exports = {\n  chainWebpack: config => {\n    config.plugin('html')."
  },
  {
    "path": "configure.js",
    "chars": 2289,
    "preview": "const bodyParser = require(\"body-parser\");\nconst debug = require(\"debug\")(\"action-dashboard:configure\");\nconst express ="
  },
  {
    "path": "getinstallationid.js",
    "chars": 915,
    "preview": "require('dotenv').config()\nconst { createAppAuth } = require(\"@octokit/auth-app\");\nconst { Octokit } = require(\"@octokit"
  },
  {
    "path": "github.js",
    "chars": 3220,
    "preview": "const { createAppAuth } = require(\"@octokit/auth-app\");\nconst { throttling } = require(\"@octokit/plugin-throttling\");\nco"
  },
  {
    "path": "index.js",
    "chars": 896,
    "preview": "try {\n    const { resolve } = require('path');\n    const history = require('connect-history-api-fallback');\n    const ex"
  },
  {
    "path": "jest.config.js",
    "chars": 6695,
    "preview": "/*\n * For a detailed explanation regarding each configuration property, visit:\n * https://jestjs.io/docs/configuration\n "
  },
  {
    "path": "package.json",
    "chars": 1224,
    "preview": "{\n  \"name\": \"github-action-dashboard\",\n  \"version\": \"1.6.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n "
  },
  {
    "path": "routes.js",
    "chars": 725,
    "preview": "const debug = require(\"debug\")(\"action-dashboard:routes\");\n\nclass Routes {\n  constructor(actions, owner) {\n    this._own"
  },
  {
    "path": "runstatus.js",
    "chars": 449,
    "preview": "const debug = require(\"debug\")(\"action-dashboard:runstatus\");\n\nclass RunStatus {\n  start(server) {\n    debug(\"initializi"
  },
  {
    "path": "tests/integration/github.test.js",
    "chars": 4275,
    "preview": "const { TestWatcher } = require(\"jest\");\nconst GitHub = require(\"../../github\");\n\n// Requires environment variables to b"
  },
  {
    "path": "tests/unit/actions.test.js",
    "chars": 5381,
    "preview": "const Actions = require(\"../../actions\");\n\nconst mockData = require(\"./mock_data\");\n\nafterEach(() => {\n  jest.restoreAll"
  },
  {
    "path": "tests/unit/mock_data.js",
    "chars": 436334,
    "preview": "module.exports = {\n  repos: [\n    {\n      name: \"github-action-dashboard\",\n      owner: {\n        login: \"chriskinsman\","
  },
  {
    "path": "tests/unit/runstatus.test.js",
    "chars": 900,
    "preview": "const { createServer } = require(\"http\");\nconst { Server } = require(\"socket.io\");\nconst Client = require(\"../../client/"
  },
  {
    "path": "tests/unit/webooks.test.js",
    "chars": 5492,
    "preview": "const WebHooks = require(\"../../webhooks\");\n\nconst axios = require(\"axios\").default;\nconst { Webhooks: OctoWebhooks } = "
  },
  {
    "path": "webhooks.js",
    "chars": 4439,
    "preview": "const debug = require(\"debug\")(\"action-dashboard:webhooks\");\nconst { Webhooks, createNodeMiddleware } = require(\"@octoki"
  }
]

About this extraction

This page contains the full source code of the chriskinsman/github-action-dashboard GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 35 files (489.5 KB), approximately 120.4k tokens, and a symbol index with 26 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!