diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 61c651ea..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,10 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "npm" - directory: "/" - schedule: - interval: "daily" - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "daily" diff --git a/.github/workflows/dependabot.yml b/.github/workflows/dependabot.yml deleted file mode 100644 index ecb1772b..00000000 --- a/.github/workflows/dependabot.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: Dependabot PR CI -on: - schedule: - - cron: "0 */6 * * *" - workflow_dispatch: -jobs: - label-approve: - name: Label and approve minor/patch updates - runs-on: ubuntu-18.04 - steps: - - uses: koj-co/dependabot-pr-action@master - with: - token: ${{ secrets.GH_PAT }} - merge-minor: true - merge-patch: true diff --git a/src/automations.ts b/src/automations.ts index 692d73df..06148e8b 100644 --- a/src/automations.ts +++ b/src/automations.ts @@ -3,11 +3,12 @@ import { join } from "path"; import { Octokit } from "@octokit/rest"; import { config } from "dotenv"; import axios from "axios"; +import { getSecret } from "./helpers/secrets"; config(); const createAutomatedIssue = async () => { const octokit = new Octokit({ - auth: process.env.AUTOMATION_TOKEN, + auth: getSecret("AUTOMATION_TOKEN"), }); const searchResults = await octokit.search.repos({ q: "topic:upptime", diff --git a/src/dependencies.ts b/src/dependencies.ts index 2d7eb165..794b4071 100644 --- a/src/dependencies.ts +++ b/src/dependencies.ts @@ -3,9 +3,10 @@ import { join } from "path"; import { getConfig } from "./helpers/config"; import { commit, push } from "./helpers/git"; import { getOctokit } from "./helpers/github"; +import { getOwnerRepo } from "./helpers/secrets"; export const updateDependencies = async () => { - let [owner, repo] = (process.env.GITHUB_REPOSITORY || "").split("/"); + const [owner, repo] = getOwnerRepo(); if (`${owner}/${repo}` !== "upptime/upptime") return; const config = await getConfig(); diff --git a/src/helpers/calculate-response-time.ts b/src/helpers/calculate-response-time.ts index 112bdab0..de700525 100644 --- a/src/helpers/calculate-response-time.ts +++ b/src/helpers/calculate-response-time.ts @@ -3,6 +3,7 @@ import { Downtimes } from "../interfaces"; import { getConfig } from "./config"; import { getOctokit } from "./github"; import { Octokit } from "@octokit/rest"; +import { getOwnerRepo } from "./secrets"; /** Calculate the average of some numbers */ const avg = (array: number[]) => (array.length ? array.reduce((a, b) => a + b) / array.length : 0); @@ -35,7 +36,7 @@ const getHistoryItems = async ( export const getResponseTimeForSite = async ( slug: string ): Promise> => { - let [owner, repo] = (process.env.GITHUB_REPOSITORY || "").split("/"); + const [owner, repo] = getOwnerRepo(); const octokit = await getOctokit(); const config = await getConfig(); diff --git a/src/helpers/calculate-uptime.ts b/src/helpers/calculate-uptime.ts index c9112454..0cce5224 100644 --- a/src/helpers/calculate-uptime.ts +++ b/src/helpers/calculate-uptime.ts @@ -5,13 +5,14 @@ import { join } from "path"; import { DownPecentages, Downtimes, SiteHistory } from "../interfaces"; import { getOctokit } from "./github"; import { checkOverlap } from "./overlap"; +import { getOwnerRepo } from "./secrets"; /** * Get the number of seconds a website has been down * @param slug - Slug of the site */ const getDowntimeSecondsForSite = async (slug: string): Promise => { - let [owner, repo] = (process.env.GITHUB_REPOSITORY || "").split("/"); + const [owner, repo] = getOwnerRepo(); const octokit = await getOctokit(); let day = 0; let week = 0; diff --git a/src/helpers/environment.ts b/src/helpers/environment.ts index f3cc3b87..40b1db51 100644 --- a/src/helpers/environment.ts +++ b/src/helpers/environment.ts @@ -1,6 +1,9 @@ export const replaceEnvironmentVariables = (str: string) => { - Object.keys(process.env).forEach((key) => { - str = str.replace(`$${key}`, process.env[key] || `$${key}`); + const SECRETS_CONTEXT = process.env.SECRETS_CONTEXT || "{}"; + const allSecrets: Record = JSON.parse(SECRETS_CONTEXT); + const secrets: Record = { ...JSON.parse(JSON.stringify(process.env)), allSecrets }; + Object.keys(secrets).forEach((key) => { + str = str.replace(`$${key}`, secrets[key] || `$${key}`); }); return str; }; diff --git a/src/helpers/github.ts b/src/helpers/github.ts index 581ef86e..d0ad6339 100644 --- a/src/helpers/github.ts +++ b/src/helpers/github.ts @@ -1,10 +1,11 @@ import { Octokit } from "@octokit/rest"; import { getConfig } from "./config"; +import { getSecret } from "./secrets"; export const getOctokit = async (): Promise => { const config = await getConfig(); return new Octokit({ - auth: config.PAT || process.env.GH_PAT || process.env.GITHUB_TOKEN, - userAgent: config["user-agent"] || process.env.USER_AGENT || "KojBot", + auth: config.PAT || getSecret("GH_PAT") || getSecret("GITHUB_TOKEN"), + userAgent: config["user-agent"] || getSecret("USER_AGENT") || "KojBot", }); }; diff --git a/src/helpers/init-check.ts b/src/helpers/init-check.ts index 7238d412..15ce3ade 100644 --- a/src/helpers/init-check.ts +++ b/src/helpers/init-check.ts @@ -1,9 +1,10 @@ import axios from "axios"; import { readFile } from "fs-extra"; import { join } from "path"; +import { getOwnerRepo } from "./secrets"; export const shouldContinue = async (): Promise => { - let [owner, repo] = (process.env.GITHUB_REPOSITORY || "").split("/"); + const [owner, repo] = getOwnerRepo(); if (`${owner}/${repo}` === "upptime/upptime") return true; try { const upptimeDefaultConfig = await axios.get( diff --git a/src/helpers/notifications.ts b/src/helpers/notifications.ts index f10d3291..4e5d9f97 100644 --- a/src/helpers/notifications.ts +++ b/src/helpers/notifications.ts @@ -2,6 +2,7 @@ import { UpptimeConfig } from "../interfaces"; import axios from "axios"; import nodemailer from "nodemailer"; import SMTPTransport from "nodemailer/lib/smtp-transport"; +import { getSecret } from "./secrets"; export const sendNotification = async (config: UpptimeConfig, text: string) => { console.log("[debug] Sending notification", text); @@ -9,12 +10,12 @@ export const sendNotification = async (config: UpptimeConfig, text: string) => { for await (const notification of config.notifications || []) { if (notification.type === "slack") { console.log("[debug] Sending Slack notification to channel", notification.channel); - const token = process.env.SLACK_APP_ACCESS_TOKEN; + const token = getSecret("SLACK_APP_ACCESS_TOKEN"); if (token) { const { data } = await axios.post( "https://slack.com/api/chat.postMessage", { channel: notification.channel, text }, - { headers: { Authorization: `Bearer ${process.env.SLACK_BOT_ACCESS_TOKEN}` } } + { headers: { Authorization: `Bearer ${getSecret("SLACK_BOT_ACCESS_TOKEN")}` } } ); console.log("[debug] Slack response", data); } @@ -24,26 +25,26 @@ export const sendNotification = async (config: UpptimeConfig, text: string) => { "[debug] Slack token", (token || "").split("").join(" "), { channel: notification.channel, text }, - { headers: { Authorization: `Bearer ${process.env.SLACK_BOT_ACCESS_TOKEN}` } } + { headers: { Authorization: `Bearer ${getSecret("SLACK_BOT_ACCESS_TOKEN")}` } } ); } else if (notification.type === "discord") { console.log("[debug] Sending Discord notification"); - const webhookUrl = process.env.DISCORD_WEBHOOK_URL; + const webhookUrl = getSecret("DISCORD_WEBHOOK_URL"); if (webhookUrl) await axios.post(webhookUrl, { content: text }); } else if (notification.type === "email") { console.log("[debug] Sending email notification"); const transporter = nodemailer.createTransport({ - host: process.env.NOTIFICATION_SMTP_HOST, - port: process.env.NOTIFICATION_SMTP_PORT || 587, - secure: !!process.env.NOTIFICATION_SMTP_SECURE, + host: getSecret("NOTIFICATION_SMTP_HOST"), + port: getSecret("NOTIFICATION_SMTP_PORT") || 587, + secure: !!getSecret("NOTIFICATION_SMTP_SECURE"), auth: { - user: process.env.NOTIFICATION_SMTP_USER, - pass: process.env.NOTIFICATION_SMTP_PASSWORD, + user: getSecret("NOTIFICATION_SMTP_USER"), + pass: getSecret("NOTIFICATION_SMTP_PASSWORD"), }, } as SMTPTransport.Options); await transporter.sendMail({ - from: process.env.NOTIFICATION_SMTP_USER, - to: process.env.NOTIFICATION_EMAIL || process.env.NOTIFICATION_SMTP_USER, + from: getSecret("NOTIFICATION_SMTP_USER"), + to: getSecret("NOTIFICATION_EMAIL") || getSecret("NOTIFICATION_SMTP_USER"), subject: text, text: text, html: `

${text}

`, diff --git a/src/helpers/notifme.ts b/src/helpers/notifme.ts index 31fbd8cd..96626016 100644 --- a/src/helpers/notifme.ts +++ b/src/helpers/notifme.ts @@ -2,6 +2,7 @@ import NotifmeSdk, { EmailProvider, SlackProvider, SmsProvider } from "notifme-s import axios from "axios"; import type { Channel } from "notifme-sdk"; import { replaceEnvironmentVariables } from "./environment"; +import { getSecret } from "./secrets"; const channels: { email?: Channel; @@ -9,155 +10,151 @@ const channels: { slack?: Channel; } = {}; -// Support legacy environment variables for Discord -if (process.env.DISCORD_WEBHOOK_URL) - process.env.NOTIFICATION_DISCORD_WEBHOOK_URL = process.env.DISCORD_WEBHOOK_URL; - if ( - process.env.NOTIFICATION_EMAIL_SENDGRID || - process.env.NOTIFICATION_EMAIL_SES || - process.env.NOTIFICATION_EMAIL_SPARKPOST || - process.env.NOTIFICATION_EMAIL_MAILGUN || - process.env.NOTIFICATION_EMAIL_SMTP + getSecret("NOTIFICATION_EMAIL_SENDGRID") || + getSecret("NOTIFICATION_EMAIL_SES") || + getSecret("NOTIFICATION_EMAIL_SPARKPOST") || + getSecret("NOTIFICATION_EMAIL_MAILGUN") || + getSecret("NOTIFICATION_EMAIL_SMTP") ) { channels.email = { providers: [], multiProviderStrategy: - (process.env.NOTIFICATION_EMAIL_STRATEGY as "fallback" | "roundrobin" | "no-fallback") || + (getSecret("NOTIFICATION_EMAIL_STRATEGY") as "fallback" | "roundrobin" | "no-fallback") || "roundrobin", }; - if (process.env.NOTIFICATION_EMAIL_SENDGRID) { + if (getSecret("NOTIFICATION_EMAIL_SENDGRID")) { channels.email.providers.push({ type: "sendgrid", - apiKey: process.env.NOTIFICATION_EMAIL_SENDGRID_API_KEY as string, + apiKey: getSecret("NOTIFICATION_EMAIL_SENDGRID_API_KEY") as string, }); } - if (process.env.NOTIFICATION_EMAIL_SES) { + if (getSecret("NOTIFICATION_EMAIL_SES")) { channels.email.providers.push({ type: "ses", - region: process.env.NOTIFICATION_EMAIL_SES_REGION as string, - accessKeyId: process.env.NOTIFICATION_EMAIL_SES_ACCESS_KEY_ID as string, - secretAccessKey: process.env.NOTIFICATION_EMAIL_SES_SECRET_ACCESS_KEY as string, - sessionToken: process.env.NOTIFICATION_EMAIL_SES_SESSION_TOKEN as string, + region: getSecret("NOTIFICATION_EMAIL_SES_REGION") as string, + accessKeyId: getSecret("NOTIFICATION_EMAIL_SES_ACCESS_KEY_ID") as string, + secretAccessKey: getSecret("NOTIFICATION_EMAIL_SES_SECRET_ACCESS_KEY") as string, + sessionToken: getSecret("NOTIFICATION_EMAIL_SES_SESSION_TOKEN") as string, }); } - if (process.env.NOTIFICATION_EMAIL_SPARKPOST) { + if (getSecret("NOTIFICATION_EMAIL_SPARKPOST")) { channels.email.providers.push({ type: "sparkpost", - apiKey: process.env.NOTIFICATION_EMAIL_SPARKPOST_API_KEY as string, + apiKey: getSecret("NOTIFICATION_EMAIL_SPARKPOST_API_KEY") as string, }); } - if (process.env.NOTIFICATION_EMAIL_MAILGUN) { + if (getSecret("NOTIFICATION_EMAIL_MAILGUN")) { channels.email.providers.push({ type: "mailgun", - apiKey: process.env.NOTIFICATION_EMAIL_MAILGUN_API_KEY as string, - domainName: process.env.NOTIFICATION_EMAIL_MAILGUN_DOMAIN_NAME as string, + apiKey: getSecret("NOTIFICATION_EMAIL_MAILGUN_API_KEY") as string, + domainName: getSecret("NOTIFICATION_EMAIL_MAILGUN_DOMAIN_NAME") as string, }); } - if (process.env.NOTIFICATION_EMAIL_SMTP) { + if (getSecret("NOTIFICATION_EMAIL_SMTP")) { channels.email.providers.push({ type: "smtp", - port: (process.env.NOTIFICATION_EMAIL_SMTP_PORT - ? parseInt(process.env.NOTIFICATION_EMAIL_SMTP_PORT, 10) + port: (getSecret("NOTIFICATION_EMAIL_SMTP_PORT") + ? parseInt(getSecret("NOTIFICATION_EMAIL_SMTP_PORT") || "", 10) : 587) as 587 | 25 | 465, - host: process.env.NOTIFICATION_EMAIL_SMTP_HOST as string, + host: getSecret("NOTIFICATION_EMAIL_SMTP_HOST") as string, auth: { - user: process.env.NOTIFICATION_EMAIL_SMTP_USERNAME as string, - pass: process.env.NOTIFICATION_EMAIL_SMTP_PASSWORD as string, + user: getSecret("NOTIFICATION_EMAIL_SMTP_USERNAME") as string, + pass: getSecret("NOTIFICATION_EMAIL_SMTP_PASSWORD") as string, }, }); } } if ( - process.env.NOTIFICATION_SMS_46ELKS || - process.env.NOTIFICATION_SMS_CALLR || - process.env.NOTIFICATION_SMS_CLICKATELL || - process.env.NOTIFICATION_SMS_INFOBIP || - process.env.NOTIFICATION_SMS_NEXMO || - process.env.NOTIFICATION_SMS_OVH || - process.env.NOTIFICATION_SMS_PLIVO || - process.env.NOTIFICATION_SMS_TWILIO + getSecret("NOTIFICATION_SMS_46ELKS") || + getSecret("NOTIFICATION_SMS_CALLR") || + getSecret("NOTIFICATION_SMS_CLICKATELL") || + getSecret("NOTIFICATION_SMS_INFOBIP") || + getSecret("NOTIFICATION_SMS_NEXMO") || + getSecret("NOTIFICATION_SMS_OVH") || + getSecret("NOTIFICATION_SMS_PLIVO") || + getSecret("NOTIFICATION_SMS_TWILIO") ) { channels.sms = { providers: [], multiProviderStrategy: - (process.env.NOTIFICATION_SMS_STRATEGY as "fallback" | "roundrobin" | "no-fallback") || + (getSecret("NOTIFICATION_SMS_STRATEGY") as "fallback" | "roundrobin" | "no-fallback") || "roundrobin", }; - if (process.env.NOTIFICATION_SMS_46ELKS) { + if (getSecret("NOTIFICATION_SMS_46ELKS")) { channels.sms.providers.push({ type: "46elks", - apiUsername: process.env.NOTIFICATION_SMS_46ELKS_API_USERNAME as string, - apiPassword: process.env.NOTIFICATION_SMS_46ELKS_API_PASSWORD as string, + apiUsername: getSecret("NOTIFICATION_SMS_46ELKS_API_USERNAME") as string, + apiPassword: getSecret("NOTIFICATION_SMS_46ELKS_API_PASSWORD") as string, }); } - if (process.env.NOTIFICATION_SMS_CALLR) { + if (getSecret("NOTIFICATION_SMS_CALLR")) { channels.sms.providers.push({ type: "callr", - login: process.env.NOTIFICATION_SMS_CALLR_LOGIN as string, - password: process.env.NOTIFICATION_SMS_CALLR_PASSWORD as string, + login: getSecret("NOTIFICATION_SMS_CALLR_LOGIN") as string, + password: getSecret("NOTIFICATION_SMS_CALLR_PASSWORD") as string, }); } - if (process.env.NOTIFICATION_SMS_CLICKATELL) { + if (getSecret("NOTIFICATION_SMS_CLICKATELL")) { channels.sms.providers.push({ type: "clickatell", - apiKey: process.env.NOTIFICATION_SMS_CLICKATELL_API_KEY as string, + apiKey: getSecret("NOTIFICATION_SMS_CLICKATELL_API_KEY") as string, }); } - if (process.env.NOTIFICATION_SMS_INFOBIP) { + if (getSecret("NOTIFICATION_SMS_INFOBIP")) { channels.sms.providers.push({ type: "infobip", - username: process.env.NOTIFICATION_SMS_INFOBIP_USERNAME as string, - password: process.env.NOTIFICATION_SMS_INFOBIP_PASSWORD as string, + username: getSecret("NOTIFICATION_SMS_INFOBIP_USERNAME") as string, + password: getSecret("NOTIFICATION_SMS_INFOBIP_PASSWORD") as string, }); } - if (process.env.NOTIFICATION_SMS_NEXMO) { + if (getSecret("NOTIFICATION_SMS_NEXMO")) { channels.sms.providers.push({ type: "nexmo", - apiKey: process.env.NOTIFICATION_SMS_NEXMO_API_KEY as string, - apiSecret: process.env.NOTIFICATION_SMS_NEXMO_API_SECRET as string, + apiKey: getSecret("NOTIFICATION_SMS_NEXMO_API_KEY") as string, + apiSecret: getSecret("NOTIFICATION_SMS_NEXMO_API_SECRET") as string, }); } - if (process.env.NOTIFICATION_SMS_OVH) { + if (getSecret("NOTIFICATION_SMS_OVH")) { channels.sms.providers.push({ type: "ovh", - appKey: process.env.NOTIFICATION_SMS_OVH_APP_KEY as string, - appSecret: process.env.NOTIFICATION_SMS_OVH_APP_SECRET as string, - consumerKey: process.env.NOTIFICATION_SMS_OVH_CONSUMER_KEY as string, - account: process.env.NOTIFICATION_SMS_OVH_ACCOUNT as string, - host: process.env.NOTIFICATION_SMS_OVH_HOST as string, + appKey: getSecret("NOTIFICATION_SMS_OVH_APP_KEY") as string, + appSecret: getSecret("NOTIFICATION_SMS_OVH_APP_SECRET") as string, + consumerKey: getSecret("NOTIFICATION_SMS_OVH_CONSUMER_KEY") as string, + account: getSecret("NOTIFICATION_SMS_OVH_ACCOUNT") as string, + host: getSecret("NOTIFICATION_SMS_OVH_HOST") as string, }); } - if (process.env.NOTIFICATION_SMS_PLIVO) { + if (getSecret("NOTIFICATION_SMS_PLIVO")) { channels.sms.providers.push({ type: "plivo", - authId: process.env.NOTIFICATION_SMS_PLIVO_AUTH_ID as string, - authToken: process.env.NOTIFICATION_SMS_PLIVO_AUTH_TOKEN as string, + authId: getSecret("NOTIFICATION_SMS_PLIVO_AUTH_ID") as string, + authToken: getSecret("NOTIFICATION_SMS_PLIVO_AUTH_TOKEN") as string, }); } - if (process.env.NOTIFICATION_SMS_TWILIO) { + if (getSecret("NOTIFICATION_SMS_TWILIO")) { channels.sms.providers.push({ type: "twilio", - accountSid: process.env.NOTIFICATION_SMS_TWILIO_ACCOUNT_SID as string, - authToken: process.env.NOTIFICATION_SMS_TWILIO_AUTH_TOKEN as string, + accountSid: getSecret("NOTIFICATION_SMS_TWILIO_ACCOUNT_SID") as string, + authToken: getSecret("NOTIFICATION_SMS_TWILIO_AUTH_TOKEN") as string, }); } } -if (process.env.NOTIFICATION_SLACK) { +if (getSecret("NOTIFICATION_SLACK")) { channels.slack = { providers: [], multiProviderStrategy: - (process.env.NOTIFICATION_SLACK_STRATEGY as "fallback" | "roundrobin" | "no-fallback") || + (getSecret("NOTIFICATION_SLACK_STRATEGY") as "fallback" | "roundrobin" | "no-fallback") || "roundrobin", }; - if (process.env.NOTIFICATION_SLACK_WEBHOOK) { + if (getSecret("NOTIFICATION_SLACK_WEBHOOK")) { channels.slack.providers.push({ type: "webhook", - webhookUrl: process.env.NOTIFICATION_SLACK_WEBHOOK_URL as string, + webhookUrl: getSecret("NOTIFICATION_SLACK_WEBHOOK_URL") as string, }); } } @@ -175,8 +172,8 @@ export const sendNotification = async (message: string) => { try { await notifier.send({ email: { - from: (process.env.NOTIFICATION_EMAIL_FROM || process.env.NOTIFICATION_EMAIL) as string, - to: (process.env.NOTIFICATION_EMAIL_TO || process.env.NOTIFICATION_EMAIL) as string, + from: (getSecret("NOTIFICATION_EMAIL_FROM") || getSecret("NOTIFICATION_EMAIL")) as string, + to: (getSecret("NOTIFICATION_EMAIL_TO") || getSecret("NOTIFICATION_EMAIL")) as string, subject: message, html: message, }, @@ -192,8 +189,8 @@ export const sendNotification = async (message: string) => { try { await notifier.send({ sms: { - from: process.env.NOTIFICATION_SMS_FROM as string, - to: process.env.NOTIFICATION_SMS_TO as string, + from: getSecret("NOTIFICATION_SMS_FROM") as string, + to: getSecret("NOTIFICATION_SMS_TO") as string, text: message, }, }); @@ -217,10 +214,10 @@ export const sendNotification = async (message: string) => { } console.log("Finished sending Slack"); } - if (process.env.NOTIFICATION_DISCORD_WEBHOOK_URL) { + if (getSecret("NOTIFICATION_DISCORD_WEBHOOK_URL")) { console.log("Sending Discord"); try { - await axios.post(process.env.NOTIFICATION_DISCORD_WEBHOOK_URL as string, { + await axios.post(getSecret("NOTIFICATION_DISCORD_WEBHOOK_URL") as string, { content: message, }); console.log("Success Discord"); @@ -229,15 +226,15 @@ export const sendNotification = async (message: string) => { } console.log("Finished sending Discord"); } - if (process.env.NOTIFICATION_TELEGRAM && process.env.NOTIFICATION_TELEGRAM_BOT_KEY) { + if (getSecret("NOTIFICATION_TELEGRAM") && getSecret("NOTIFICATION_TELEGRAM_BOT_KEY")) { console.log("Sending Telegram"); try { await axios.post( - `https://api.telegram.org/bot${process.env.NOTIFICATION_TELEGRAM_BOT_KEY}/sendMessage`, + `https://api.telegram.org/bot${getSecret("NOTIFICATION_TELEGRAM_BOT_KEY")}/sendMessage`, { parse_mode: "Markdown", disable_web_page_preview: true, - chat_id: process.env.NOTIFICATION_TELEGRAM_CHAT_ID, + chat_id: getSecret("NOTIFICATION_TELEGRAM_CHAT_ID"), text: message, } ); diff --git a/src/helpers/secrets.ts b/src/helpers/secrets.ts new file mode 100644 index 00000000..8b13886d --- /dev/null +++ b/src/helpers/secrets.ts @@ -0,0 +1,14 @@ +/** Get a secret from the context or an environment variable */ +export const getSecret = (key: string) => { + const SECRETS_CONTEXT = process.env.SECRETS_CONTEXT || "{}"; + const allSecrets: Record = JSON.parse(SECRETS_CONTEXT); + if (allSecrets[key]) return allSecrets[key]; + return process.env[key]; +}; + +/** Get the GitHub repo */ +export const getOwnerRepo = (): [string, string] => { + const result = (getSecret("GITHUB_REPOSITORY") || "").split("/"); + if (result.length !== 2) throw new Error("Unable to find GitHub repo"); + return result as [string, string]; +} diff --git a/src/index.ts b/src/index.ts index e0aa0148..94427ab0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,17 +1,13 @@ import { debug, getInput, setFailed } from "@actions/core"; import { updateDependencies } from "./dependencies"; import { generateGraphs } from "./graphs"; +import { getSecret } from "./helpers/secrets"; import { generateSite } from "./site"; import { generateSummary } from "./summary"; import { update } from "./update"; import { updateTemplate } from "./update-template"; -const token = getInput("token") || process.env.GH_PAT || process.env.GITHUB_TOKEN; -const SECRETS_CONTEXT = process.env.SECRETS_CONTEXT || "{}"; -const allSecrets: Record = JSON.parse(SECRETS_CONTEXT); -Object.keys(allSecrets).forEach((key) => { - process.env[key] = allSecrets[key]; -}); +const token = getSecret("GH_PAT") || getInput("token") || getSecret("GITHUB_TOKEN"); export const run = async () => { if (!token) throw new Error("GitHub token not found"); diff --git a/src/site.ts b/src/site.ts index 783c8d27..c4c7146d 100644 --- a/src/site.ts +++ b/src/site.ts @@ -2,10 +2,11 @@ import { cd, cp, exec, mkdir } from "shelljs"; import { getConfig } from "./helpers/config"; import { getOctokit } from "./helpers/github"; import { shouldContinue } from "./helpers/init-check"; +import { getOwnerRepo } from "./helpers/secrets"; export const generateSite = async () => { if (!(await shouldContinue())) return; - let [owner, repo] = (process.env.GITHUB_REPOSITORY || "").split("/"); + const [owner, repo] = getOwnerRepo(); const config = await getConfig(); if (config.skipGeneratingWebsite) return; const sitePackage = config.customStatusWebsitePackage || "@upptime/status-page"; diff --git a/src/summary.ts b/src/summary.ts index 4d600217..00897500 100644 --- a/src/summary.ts +++ b/src/summary.ts @@ -10,12 +10,12 @@ import { getOctokit } from "./helpers/github"; import { shouldContinue } from "./helpers/init-check"; import { SiteStatus } from "./interfaces"; import { parse } from "url"; +import { getOwnerRepo } from "./helpers/secrets"; export const generateSummary = async () => { if (!(await shouldContinue())) return; await mkdirp("history"); - let [owner, repo] = (process.env.GITHUB_REPOSITORY || "").split("/"); - + const [owner, repo] = getOwnerRepo(); const config = await getConfig(); const octokit = await getOctokit(); diff --git a/src/update-template.ts b/src/update-template.ts index 1598d4be..9ae5e4e6 100644 --- a/src/update-template.ts +++ b/src/update-template.ts @@ -3,6 +3,7 @@ import { ensureDir, readdir, remove, writeFile } from "fs-extra"; import { join } from "path"; import { getConfig } from "./helpers/config"; import { commit, push } from "./helpers/git"; +import { getOwnerRepo } from "./helpers/secrets"; import { graphsCiWorkflow, responseTimeCiWorkflow, @@ -16,7 +17,7 @@ import { } from "./helpers/workflows"; export const updateTemplate = async () => { - const [owner, repo] = (process.env.GITHUB_REPOSITORY || "").split("/"); + const [owner, repo] = getOwnerRepo(); const config = await getConfig(); // Remove our workflows (not all workflows) diff --git a/src/update.ts b/src/update.ts index 3f741a9f..c30c305e 100644 --- a/src/update.ts +++ b/src/update.ts @@ -11,13 +11,14 @@ import { shouldContinue } from "./helpers/init-check"; import { sendNotification } from "./helpers/notifme"; import { ping } from "./helpers/ping"; import { curl } from "./helpers/request"; +import { getOwnerRepo } from "./helpers/secrets"; import { SiteHistory } from "./interfaces"; import { generateSummary } from "./summary"; export const update = async (shouldCommit = false) => { if (!(await shouldContinue())) return; await mkdirp("history"); - let [owner, repo] = (process.env.GITHUB_REPOSITORY || "").split("/"); + const [owner, repo] = getOwnerRepo(); const config = await getConfig(); const octokit = await getOctokit();