diff --git a/Dockerfile.web b/Dockerfile.web new file mode 100644 index 00000000000..df0acce5244 --- /dev/null +++ b/Dockerfile.web @@ -0,0 +1,38 @@ +# Base image +FROM node:20-bookworm-slim + +# Copy repository +COPY . /metrics +WORKDIR /metrics + +# Setup +RUN chmod +x /metrics/source/app/action/index.mjs \ + # Install latest chrome dev package, fonts to support major charsets and skip chromium download on puppeteer install + # Based on https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#running-puppeteer-in-docker + && apt-get update \ + && apt-get install -y wget gnupg ca-certificates libgconf-2-4 \ + && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ + && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \ + && apt-get update \ + && apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 libx11-xcb1 libxtst6 lsb-release --no-install-recommends \ + # Install deno for miscellaneous scripts + && apt-get install -y curl unzip \ + && curl -fsSL https://deno.land/x/install/install.sh | DENO_INSTALL=/usr/local sh \ + # Install ruby to support github licensed gem + && apt-get install -y ruby-full git g++ cmake pkg-config libssl-dev \ + && gem install licensed \ + # Install python for node-gyp + && apt-get install -y python3 \ + # Clean apt/lists + && rm -rf /var/lib/apt/lists/* \ + # Install node modules and rebuild indexes + && npm ci \ + && npm run build + +# Environment variables +ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true +ENV PUPPETEER_BROWSER_PATH="google-chrome-stable" +ENV NODE_ENV=production + +# Run web server +CMD ["npm", "start"] diff --git a/Procfile b/Procfile new file mode 100644 index 00000000000..063b78f4631 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: npm start diff --git a/heroku.yml b/heroku.yml new file mode 100644 index 00000000000..4502a037805 --- /dev/null +++ b/heroku.yml @@ -0,0 +1,3 @@ +build: + docker: + web: Dockerfile.web diff --git a/source/app/metrics/setup.mjs b/source/app/metrics/setup.mjs index 28fc20c32f5..81e22593173 100644 --- a/source/app/metrics/setup.mjs +++ b/source/app/metrics/setup.mjs @@ -30,7 +30,7 @@ export default async function({log = true, sandbox = false, community = {}, extr authenticated: null, templates: {}, queries: {}, - settings: {port: 3000}, + settings: {port: Number(process.env.PORT) || 3000}, metadata: {}, paths: { statics: __statics, @@ -63,6 +63,12 @@ export default async function({log = true, sandbox = false, community = {}, extr } } + //Environment variables override (for Heroku/Docker deployment) + if (process.env.METRICS_TOKEN) + conf.settings.token = process.env.METRICS_TOKEN + if (process.env.PORT) + conf.settings.port = Number(process.env.PORT) + if (!conf.settings.templates) conf.settings.templates = {default: "classic", enabled: []} if (!conf.settings.plugins) diff --git a/source/plugins/achievements/list/users.mjs b/source/plugins/achievements/list/users.mjs index 8b4ef03814e..d1d841715ca 100644 --- a/source/plugins/achievements/list/users.mjs +++ b/source/plugins/achievements/list/users.mjs @@ -53,21 +53,17 @@ export default async function({list, login, data, computed, imports, graphql, qu }) } - //Manager - { - const value = user.projects.totalCount - const unlock = user.projects.nodes?.shift() - - list.push({ - title: "Manager", - text: `Created ${value} user project${imports.s(value)}`, - icon: - '', - ...rank(value, [1, 2, 3, 4, 5]), - value, - unlock: new Date(unlock?.createdAt), - }) - } + //Manager - DISABLED: Projects (classic) has been deprecated by GitHub (May 2024) + //See: https://github.blog/changelog/2024-05-23-sunset-notice-projects-classic/ + //{ + // const value = user.projects?.totalCount ?? 0 + // const unlock = user.projects?.nodes?.shift() + // list.push({ + // title: "Manager", + // text: `Created ${value} user project${imports.s(value)}`, + // ... + // }) + //} //Reviewer { diff --git a/source/plugins/achievements/queries/achievements.graphql b/source/plugins/achievements/queries/achievements.graphql index c7bcb13b334..3960f3d8fe3 100644 --- a/source/plugins/achievements/queries/achievements.graphql +++ b/source/plugins/achievements/queries/achievements.graphql @@ -47,12 +47,11 @@ query AchievementsDefault { totalCount } } - projects(first: 1, orderBy: {field: CREATED_AT, direction: ASC}) { - totalCount - #nodes { This requires additional scopes :/ - # name - #} - } + # Projects (classic) has been deprecated by GitHub (May 2024) + # See: https://github.blog/changelog/2024-05-23-sunset-notice-projects-classic/ + # projects(first: 1, orderBy: {field: CREATED_AT, direction: ASC}) { + # totalCount + # } packages(first: 1, orderBy: {direction: ASC, field: CREATED_AT}) { totalCount #nodes { This requires additional scopes :/ diff --git a/source/plugins/activity/index.mjs b/source/plugins/activity/index.mjs index fcebc868404..ac6cd2115ff 100644 --- a/source/plugins/activity/index.mjs +++ b/source/plugins/activity/index.mjs @@ -137,7 +137,7 @@ export default async function({login, data, rest, q, account, imports}, {enabled //Pushed commits case "PushEvent": { let {size, commits, ref} = payload - commits = commits.filter(({author: {email}}) => imports.filters.text(email, ignored)) + commits = commits.filter(commit => commit.author && imports.filters.text(commit.author.email, ignored)) if (!commits.length) return null if (commits.slice(-1).pop()?.message.startsWith("Merge branch ")) diff --git a/source/plugins/habits/index.mjs b/source/plugins/habits/index.mjs index 3a1a437d602..1e244aefc7a 100644 --- a/source/plugins/habits/index.mjs +++ b/source/plugins/habits/index.mjs @@ -48,6 +48,7 @@ export default async function({login, data, rest, imports, q, account}, {enabled ...await Promise.allSettled( commits .flatMap(({payload}) => payload.commits) + .filter(commit => commit && commit.author) // Filter out commits without author .filter(({author}) => data.shared["commits.authoring"].filter(authoring => author?.login?.toLocaleLowerCase().includes(authoring) || author?.email?.toLocaleLowerCase().includes(authoring) || author?.name?.toLocaleLowerCase().includes(authoring)).length) .map(async commit => (await rest.request(commit)).data.files), ),