From 7bc3c990e02adf7a4bb480278c2ddb14810adfa7 Mon Sep 17 00:00:00 2001 From: Niccolo Borgioli Date: Sat, 27 Jan 2024 01:26:37 +0100 Subject: [PATCH 1/2] logging --- src/api/gitea.ts | 18 +++++++++++------- src/api/github.ts | 7 +++++++ src/config.ts | 10 ---------- src/core.ts | 24 +++++++++++++----------- 4 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/api/gitea.ts b/src/api/gitea.ts index 6430a3f..640521f 100644 --- a/src/api/gitea.ts +++ b/src/api/gitea.ts @@ -12,6 +12,8 @@ const Base = axios.create({ }, }) +const l = logger.child({ api: 'gitea' }) + export type MirrorOptions = { private: boolean auth_token: string @@ -20,7 +22,7 @@ export type MirrorOptions = { } export async function mirror(options: MirrorOptions) { try { - logger.debug('Mirroring repository', options) + l.debug('mirroring repository', options) const response = await Base({ url: '/repos/migrate', method: 'POST', @@ -41,18 +43,19 @@ export async function mirror(options: MirrorOptions) { releases: true, }, }) - logger.debug('Mirrored repository', { data: response.data }) + l.debug('mirrored repository', { data: response.data }) return response.data } catch (e) { if (e instanceof AxiosError) { - logger.error('Error mirroring repository', e.response?.data) + l.error('Error mirroring repository', e.response?.data) } else { - logger.error('Unknown error', e) + l.error('Unknown error', e) } } } export async function listRepositories(page: number, limit: number) { + l.debug(`listing repos`, { page, limit }) const response = await Base({ url: '/user/repos', method: 'GET', @@ -65,22 +68,23 @@ export async function listRepositories(page: number, limit: number) { } export async function listAllRepositories() { - logger.debug('Listing all repositories in Gitea') + l.debug('listing all repositories') const limit = 50 const repos: ListRepositoriesResponse = [] let page = 1 while (true) { + l.debug('listing page', { page }) const response = await listRepositories(page, limit) repos.push(...response) if (response.length < limit) break page++ } - logger.debug('Listed all repositories in Gitea', { data: repos }) + l.debug('listed all repositories', { repos: repos.map((repo) => repo.name) }) return repos } export async function updateRepository(owner: string, repo: string, body: Partial) { - logger.debug('Updating repository', { owner, repo, body }) + l.debug('updating repository', { owner, repo, body }) await Base({ url: `/repos/${owner}/${repo}`, method: 'PATCH', diff --git a/src/api/github.ts b/src/api/github.ts index 2fb6812..74eddc0 100644 --- a/src/api/github.ts +++ b/src/api/github.ts @@ -2,6 +2,7 @@ import axios from 'axios' import { Config } from '../config.js' import type { ListRepositoriesResponse } from './github.types.js' +import { logger } from '../logger.js' const Base = axios.create({ baseURL: 'https://api.github.com', @@ -12,7 +13,10 @@ const Base = axios.create({ }, }) +const l = logger.child({ api: 'github' }) + async function listRepos(page: number, limit: number) { + l.debug('listing repos', { page, limit }) const response = await Base({ url: `user/repos`, method: 'GET', @@ -26,14 +30,17 @@ async function listRepos(page: number, limit: number) { } export async function listAllRepositories() { + l.debug('listing all repos') const limit = 100 const repos: ListRepositoriesResponse = [] let page = 1 while (true) { + l.debug('listing page', { page }) const response = await listRepos(page, limit) repos.push(...response) if (response.length < limit) break page++ } + l.debug('listed all repos') return repos } diff --git a/src/config.ts b/src/config.ts index 02b97b1..8b5a127 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,7 +1,3 @@ -import { config } from 'dotenv' - -config() - function getEnv(key: string, fallback: string, parse?: undefined, validator?: (s: string) => boolean): string function getEnv(key: string, fallback: T, parse: (value: string) => T, validator?: (T: string) => boolean): T function getEnv( @@ -19,12 +15,6 @@ function getEnv( return parsed } -function parseBoolean(value: string): boolean { - value = value.toLowerCase() - const truthy = ['true', 'yes', '1', 'y'] - return truthy.includes(value) -} - function isPresent(s: string): boolean { return s.length > 0 } diff --git a/src/core.ts b/src/core.ts index 14f49cd..8e84463 100644 --- a/src/core.ts +++ b/src/core.ts @@ -5,30 +5,32 @@ import { logger } from './logger.js' let running = false +const l = logger.child({ context: 'runner' }) + export async function sync() { if (running) { - logger.info('Already running, skipping') + l.info('already running, skipping') return } try { - logger.info('Starting sync') + l.info('starting sync') const syncedRepos = await giteaRepos() const toSync = await githubRepos() - logger.debug('Loaded repos', { remote: toSync.length, local: syncedRepos.length }) + l.debug('loaded repos', { remote: toSync.length, local: syncedRepos.length }) for (const repo of toSync) { + const lr = l.child({ repo: repo.name }) const sameName = syncedRepos.find((r) => r.name === repo.name || r.original_url === repo.clone_url) if (sameName) { if (sameName.original_url === repo.clone_url) { if (sameName.private === repo.private) logger.info('Already synced, skipping', { name: repo.name }) else { - logger.info('Visibility changed, updating', { name: repo.name }) + lr.info('visibility changed, updating') const [owner, repository] = sameName.full_name.split('/') await updateRepository(owner, repository, { private: repo.private }) } } else { - logger.error('Repo with same name but different url', { - name: repo.name, + lr.error('repo with same name but different url', { url: repo.clone_url, original_url: sameName.original_url, }) @@ -42,14 +44,14 @@ export async function sync() { private: repo.private, auth_token: Config.github.token, } - logger.info('Mirroring repository', options) + lr.info('mirroring repository', options) await mirror(options) - logger.info('Mirrored repository', { name: repo.name }) + lr.info('mirrored repository') } - logger.info('Finished sync') + l.info('Finished sync') } catch (error) { - logger.debug(error) - logger.error('Failed to sync', { error: error instanceof Error ? error.message : 'Unknown error' }) + l.debug(error) + l.error('Failed to sync', { error: error instanceof Error ? error.message : 'Unknown error' }) } finally { running = false } From ee25d7db596b14febdee5f120a9c1abebd1180f4 Mon Sep 17 00:00:00 2001 From: Niccolo Borgioli Date: Sat, 27 Jan 2024 01:26:52 +0100 Subject: [PATCH 2/2] move to bun --- .dockerignore | 3 +- .nvmrc | 1 - Dockerfile | 22 +--- README.md | 2 +- bun.lockb | Bin 0 -> 17201 bytes docker-compose.yaml | 6 +- package.json | 15 +-- pnpm-lock.yaml | 302 -------------------------------------------- 8 files changed, 19 insertions(+), 332 deletions(-) delete mode 100644 .nvmrc create mode 100755 bun.lockb delete mode 100644 pnpm-lock.yaml diff --git a/.dockerignore b/.dockerignore index 31e17c1..e3ef112 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,4 @@ * !package.json -!pnpm-lock.yaml +!bun.lockb !src -!tsconfig.json diff --git a/.nvmrc b/.nvmrc deleted file mode 100644 index 932b2b0..0000000 --- a/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -18.15 diff --git a/Dockerfile b/Dockerfile index dfa6950..eda8b4c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,11 @@ -FROM node:18.15-alpine as base - -RUN npm -g install pnpm@7 +FROM oven/bun:1 as base WORKDIR /app -COPY package.json pnpm-lock.yaml ./ -FROM base as build -RUN pnpm install --frozen-lockfile +FROM base as builder COPY . . -RUN pnpm run build - -FROM base as runner -RUN pnpm install --frozen-lockfile --prod -COPY --from=build /app/dist /app/dist -CMD ["pnpm", "run", "start"] - - - +RUN bun install --production --frozen-lockfile +RUN bun build --target bun --minify src/index.ts --outfile app.js +FROM base +COPY --from=builder /app/app.js . +ENTRYPOINT [ "bun", "run", "app.js" ] diff --git a/README.md b/README.md index ec6c3fb..621e631 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ GITHUB_TOKEN= # Host of the Gitea server GITEA_HOST= -# Gitea token (scopes: repo) +# Gitea token (scopes: repos: read and write; user: read) GITEA_TOKEN= # OPTIONAL diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..7005452bd8b6b57b1b33f9329cdf3c6c7f47fef0 GIT binary patch literal 17201 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 b=0.1.90'} - dev: false - - /@dabh/diagnostics@2.0.3: - resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} - dependencies: - colorspace: 1.1.4 - enabled: 2.0.0 - kuler: 2.0.0 - dev: false - - /@types/node-cron@3.0.7: - resolution: {integrity: sha512-9PuLtBboc/+JJ7FshmJWv769gDonTpItN0Ol5TMwclpSQNjVyB2SRxSKBcTtbSysSL5R7Oea06kTTFNciCoYwA==} - dev: true - - /@types/node@18.14.6: - resolution: {integrity: sha512-93+VvleD3mXwlLI/xASjw0FzKcwzl3OdTCzm1LaRfqgS21gfFtK3zDXM5Op9TeeMsJVOaJ2VRDpT9q4Y3d0AvA==} - dev: true - - /@types/triple-beam@1.3.2: - resolution: {integrity: sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g==} - dev: false - - /async@3.2.4: - resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} - dev: false - - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: false - - /axios@1.6.0: - resolution: {integrity: sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==} - dependencies: - follow-redirects: 1.15.2 - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - dev: false - - /color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - dependencies: - color-name: 1.1.3 - dev: false - - /color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - dev: false - - /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: false - - /color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - dependencies: - color-name: 1.1.4 - simple-swizzle: 0.2.2 - dev: false - - /color@3.2.1: - resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} - dependencies: - color-convert: 1.9.3 - color-string: 1.9.1 - dev: false - - /colorspace@1.1.4: - resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} - dependencies: - color: 3.2.1 - text-hex: 1.0.0 - dev: false - - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - dev: false - - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dev: false - - /dotenv@16.0.3: - resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} - engines: {node: '>=12'} - dev: false - - /enabled@2.0.0: - resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} - dev: false - - /fecha@4.2.3: - resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} - dev: false - - /fn.name@1.1.0: - resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} - dev: false - - /follow-redirects@1.15.2: - resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false - - /form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: false - - /is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} - dev: false - - /is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - dev: false - - /kuler@2.0.0: - resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} - dev: false - - /logform@2.5.1: - resolution: {integrity: sha512-9FyqAm9o9NKKfiAKfZoYo9bGXXuwMkxQiQttkT4YjjVtQVIQtK6LmVtlxmCaFswo6N4AfEkHqZTV0taDtPotNg==} - dependencies: - '@colors/colors': 1.5.0 - '@types/triple-beam': 1.3.2 - fecha: 4.2.3 - ms: 2.1.3 - safe-stable-stringify: 2.4.2 - triple-beam: 1.3.0 - dev: false - - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - dev: false - - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: false - - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: false - - /node-cron@3.0.2: - resolution: {integrity: sha512-iP8l0yGlNpE0e6q1o185yOApANRe47UPbLf4YxfbiNHt/RU5eBcGB/e0oudruheSf+LQeDMezqC5BVAb5wwRcQ==} - engines: {node: '>=6.0.0'} - dependencies: - uuid: 8.3.2 - dev: false - - /one-time@1.0.0: - resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} - dependencies: - fn.name: 1.1.0 - dev: false - - /proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - dev: false - - /readable-stream@3.6.1: - resolution: {integrity: sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==} - engines: {node: '>= 6'} - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - dev: false - - /safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: false - - /safe-stable-stringify@2.4.2: - resolution: {integrity: sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA==} - engines: {node: '>=10'} - dev: false - - /simple-swizzle@0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} - dependencies: - is-arrayish: 0.3.2 - dev: false - - /stack-trace@0.0.10: - resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} - dev: false - - /string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - dependencies: - safe-buffer: 5.2.1 - dev: false - - /text-hex@1.0.0: - resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} - dev: false - - /triple-beam@1.3.0: - resolution: {integrity: sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==} - dev: false - - /typescript@4.9.5: - resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: true - - /util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: false - - /uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - dev: false - - /winston-transport@4.5.0: - resolution: {integrity: sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==} - engines: {node: '>= 6.4.0'} - dependencies: - logform: 2.5.1 - readable-stream: 3.6.1 - triple-beam: 1.3.0 - dev: false - - /winston@3.8.2: - resolution: {integrity: sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew==} - engines: {node: '>= 12.0.0'} - dependencies: - '@colors/colors': 1.5.0 - '@dabh/diagnostics': 2.0.3 - async: 3.2.4 - is-stream: 2.0.1 - logform: 2.5.1 - one-time: 1.0.0 - readable-stream: 3.6.1 - safe-stable-stringify: 2.4.2 - stack-trace: 0.0.10 - triple-beam: 1.3.0 - winston-transport: 4.5.0 - dev: false