From 2573dbcee9249a6e9301dd0d7fd9e0b893b2ab2f Mon Sep 17 00:00:00 2001 From: Elizabeth Hunt Date: Mon, 28 Jul 2025 23:20:17 -0700 Subject: Init :3 --- .ci/bundle.js | 12 + .ci/ci.js | 3 + .ci/ci.json | 3 + .ci/ci.ts | 75 ++++ .ci/package-lock.json | 532 ++++++++++++++++++++++++ .ci/package.json | 18 + .ci/tsconfig.json | 25 ++ .dockerignore | 2 + .gitignore | 2 + Dockerfile | 64 +++ cgit.conf | 6 + cgit.nginx.conf | 23 ++ cgitrc | 17 + entrypoint.sh | 15 + static/cgit.css | 1078 +++++++++++++++++++++++++++++++++++++++++++++++++ static/cgit.png | Bin 0 -> 25036 bytes static/favicon.ico | Bin 0 -> 15406 bytes 17 files changed, 1875 insertions(+) create mode 100644 .ci/bundle.js create mode 100755 .ci/ci.js create mode 100644 .ci/ci.json create mode 100644 .ci/ci.ts create mode 100644 .ci/package-lock.json create mode 100644 .ci/package.json create mode 100644 .ci/tsconfig.json create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 cgit.conf create mode 100644 cgit.nginx.conf create mode 100644 cgitrc create mode 100755 entrypoint.sh create mode 100644 static/cgit.css create mode 100644 static/cgit.png create mode 100644 static/favicon.ico diff --git a/.ci/bundle.js b/.ci/bundle.js new file mode 100644 index 0000000..46a9ce4 --- /dev/null +++ b/.ci/bundle.js @@ -0,0 +1,12 @@ +import * as esbuild from 'esbuild'; +await esbuild + .build({ + entryPoints: ['dist/ci.js'], + bundle: true, + minify: true, + platform: 'node', + outfile: 'ci.js', + logLevel: 'info', + sourcemap: false, + }) + .catch(() => process.exit(1)); diff --git a/.ci/ci.js b/.ci/ci.js new file mode 100755 index 0000000..a294fb4 --- /dev/null +++ b/.ci/ci.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node +"use strict";var Hr=Object.create;var Ot=Object.defineProperty;var xr=Object.getOwnPropertyDescriptor;var Wr=Object.getOwnPropertyNames;var Fr=Object.getPrototypeOf,Jr=Object.prototype.hasOwnProperty;var s=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var Vr=(t,e,r,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Wr(e))!Jr.call(t,n)&&n!==r&&Ot(t,n,{get:()=>e[n],enumerable:!(i=xr(e,n))||i.enumerable});return t};var We=(t,e,r)=>(r=t!=null?Hr(Fr(t)):{},Vr(e||!t||!t.__esModule?Ot(r,"default",{value:t,enumerable:!0}):r,t));var Mt=s(me=>{"use strict";Object.defineProperty(me,"__esModule",{value:!0});me.prependWith=void 0;var $r=(t,e)=>Array(t.length*2).fill(0).map((r,i)=>i%2===0).map((r,i)=>r?e:t[Math.floor(i/2)]);me.prependWith=$r});var wt=s(F=>{"use strict";Object.defineProperty(F,"__esModule",{value:!0});F.isDebug=F.isProd=void 0;var Tt=!0,Gr=Tt&&(process.env.ENVIRONMENT??"").toLowerCase().includes("prod")?"production":"development",Yr=()=>Gr==="production";F.isProd=Yr;var Kr=!(0,F.isProd)()||Tt&&["y","t"].some((process.env.DEBUG??"").toLowerCase().startsWith),zr=()=>Kr;F.isDebug=zr});var St=s(be=>{"use strict";Object.defineProperty(be,"__esModule",{value:!0});be.memoize=void 0;var Qr=t=>{let e=new Map;return(...r)=>{let i=JSON.stringify(r);if(e.has(i))return e.get(i);let n=t(...r);return e.set(i,n),n}};be.memoize=Qr});var Et=s(L=>{"use strict";var Zr=L&&L.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,n)}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),Fe=L&&L.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&Zr(e,t,r)};Object.defineProperty(L,"__esModule",{value:!0});Fe(Mt(),L);Fe(wt(),L);Fe(St(),L)});var Pt=s(Rt=>{"use strict";Object.defineProperty(Rt,"__esModule",{value:!0})});var jt=s(_e=>{"use strict";Object.defineProperty(_e,"__esModule",{value:!0});_e.isObject=void 0;var Xr=t=>typeof t=="object"&&!Array.isArray(t)&&!!t;_e.isObject=Xr});var Lt=s(ye=>{"use strict";Object.defineProperty(ye,"__esModule",{value:!0});ye.isTagged=void 0;var kr=Je(),ei=(t,e)=>!!((0,kr.isObject)(t)&&"_tag"in t&&t._tag===e);ye.isTagged=ei});var Nt=s(qt=>{"use strict";Object.defineProperty(qt,"__esModule",{value:!0})});var Ut=s(m=>{"use strict";Object.defineProperty(m,"__esModule",{value:!0});m.Optional=m.IOptionalEmptyError=m.isOptional=m.IOptionalTag=void 0;var Ge=u();m.IOptionalTag="IOptional";var ti=t=>(0,Ge.isTagged)(t,m.IOptionalTag);m.isOptional=ti;var Oe=class extends Error{};m.IOptionalEmptyError=Oe;var It="O.Some",Dt="O.None",ie=t=>(0,Ge.isTagged)(t,Dt),At=t=>(0,Ge.isTagged)(t,It),Ve=class{_tag;constructor(e=m.IOptionalTag){this._tag=e}},$e=class t extends Ve{self;constructor(e){super(),this.self=e}move(e){return this.map(()=>e)}orSome(e){return ie(this.self)?t.from(e()):this}get(){if(ie(this.self))throw new Oe("called get() on None optional");return this.self.value}filter(e){return ie(this.self)||!e(this.self.value)?t.none():t.some(this.self.value)}map(e){return ie(this.self)?t.none():t.from(e(this.self.value))}flatMap(e){return ie(this.self)?t.none():t.from(e(this.self.value)).orSome(()=>t.none()).get()}present(){return At(this.self)}*[Symbol.iterator](){At(this.self)&&(yield this.self.value)}static some(e){return new t({value:e,_tag:It})}static _none=new t({_tag:Dt});static none(){return this._none}static from(e){return e==null?t.none():t.some(e)}};m.Optional=$e});var Ht=s(c=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0});c.Either=c.isRight=c.isLeft=c.isEither=c.IEitherTag=void 0;var J=u();c.IEitherTag="IEither";var ri=t=>(0,J.isTagged)(t,c.IEitherTag);c.isEither=ri;var Ct="E.Left",ii=t=>(0,J.isTagged)(t,Ct);c.isLeft=ii;var Bt="E.Right",ni=t=>(0,J.isTagged)(t,Bt);c.isRight=ni;var Ye=class{_tag;constructor(e=c.IEitherTag){this._tag=e}},Ke=class t extends Ye{self;constructor(e){super(),this.self=e}moveRight(e){return this.mapRight(()=>e)}mapBoth(e,r){return(0,c.isLeft)(this.self)?t.left(e(this.self.err)):t.right(r(this.self.ok))}mapRight(e){return(0,c.isRight)(this.self)?t.right(e(this.self.ok)):t.left(this.self.err)}mapLeft(e){return(0,c.isLeft)(this.self)?t.left(e(this.self.err)):t.right(this.self.ok)}flatMap(e){return(0,c.isRight)(this.self)?e(this.self.ok):t.left(this.self.err)}filter(e){return(0,c.isLeft)(this.self)?t.left(this.self.err):t.fromFailable(()=>this.right().filter(e).get())}async flatMapAsync(e){return(0,c.isLeft)(this.self)?Promise.resolve(t.left(this.self.err)):await e(this.self.ok).catch(r=>t.left(r))}fold(e,r){return(0,c.isLeft)(this.self)?e(this.self.err):r(this.self.ok)}left(){return(0,c.isLeft)(this.self)?J.Optional.from(this.self.err):J.Optional.none()}right(){return(0,c.isRight)(this.self)?J.Optional.from(this.self.ok):J.Optional.none()}joinRight(e,r){return this.flatMap(i=>e.mapRight(n=>r(n,i)))}joinRightAsync(e,r){return this.flatMapAsync(async i=>await(typeof e=="function"?e():e).then(a=>a.mapRight(o=>r(o,i))))}static left(e){return new t({err:e,_tag:Ct})}static right(e){return new t({ok:e,_tag:Bt})}static fromFailable(e){try{return t.right(e())}catch(r){return t.left(r)}}static async fromFailableAsync(e){return await(typeof e=="function"?e():e).then(r=>t.right(r)).catch(r=>t.left(r))}};c.Either=Ke});var xt=s(q=>{"use strict";var si=q&&q.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,n)}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),ze=q&&q.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&si(e,t,r)};Object.defineProperty(q,"__esModule",{value:!0});ze(Nt(),q);ze(Ut(),q);ze(Ht(),q)});var Wt=s(ee=>{"use strict";Object.defineProperty(ee,"__esModule",{value:!0});ee.ListZipper=ee.Cons=void 0;var V=u(),ne=class t{value;next;constructor(e,r=V.Optional.none()){this.value=e,this.next=r}before(e){return new t(this.value,e)}replace(e){return new t(e,this.next)}*[Symbol.iterator](){for(let e=V.Optional.some(this);e.present();e=e.flatMap(r=>r.next))yield e.get().value}static addOnto(e,r){return Array.from(e).reverse().reduce((i,n)=>V.Optional.from(new t(n,i)),r)}static from(e){return t.addOnto(e,V.Optional.none())}};ee.Cons=ne;var Qe=class t{reversedPathToHead;currentHead;constructor(e,r){this.reversedPathToHead=e,this.currentHead=r}read(){return this.currentHead.map(({value:e})=>e)}next(){return this.currentHead.map(e=>new t(V.Optional.some(e.before(this.reversedPathToHead)),e.next))}previous(){return this.reversedPathToHead.map(e=>new t(e.next,V.Optional.some(e.before(this.currentHead))))}prependChunk(e){return new t(ne.addOnto(Array.from(e).reverse(),this.reversedPathToHead),this.currentHead)}prepend(e){return this.prependChunk([e])}remove(){let e=this.currentHead.flatMap(r=>r.next);return new t(this.reversedPathToHead,e)}replace(e){let r=this.currentHead.map(i=>i.replace(e));return new t(this.reversedPathToHead,r)}*[Symbol.iterator](){let e=this;for(let r=e.previous();r.present();r=r.flatMap(i=>i.previous()))e=r.get();e.currentHead.present()&&(yield*e.currentHead.get())}collection(){return Array.from(this)}static from(e){return new t(V.Optional.none(),ne.from(e))}};ee.ListZipper=Qe});var Ft=s($=>{"use strict";var oi=$&&$.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,n)}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),ai=$&&$.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&oi(e,t,r)};Object.defineProperty($,"__esModule",{value:!0});ai(Wt(),$)});var Je=s(_=>{"use strict";var ci=_&&_.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,n)}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),se=_&&_.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&ci(e,t,r)};Object.defineProperty(_,"__esModule",{value:!0});se(Pt(),_);se(jt(),_);se(Lt(),_);se(xt(),_);se(Ft(),_)});var Jt=s(Me=>{"use strict";Object.defineProperty(Me,"__esModule",{value:!0});Me.TraceableImpl=void 0;var Ze=class t{item;trace;constructor(e,r){this.item=e,this.trace=r}map(e){let r=e(this);return new t(r,this.trace)}coExtend(e){let r=e(this);return Array.from(r).map(i=>this.move(i))}flatMap(e){return e(this)}flatMapAsync(e){return new t(e(this).then(r=>r.get()),this.trace)}traceScope(e){return new t(this.get(),this.trace.traceScope(e(this)))}peek(e){return e(this),this}move(e){return this.map(()=>e)}bimap(e){let{item:r,trace:i}=e(this);return this.move(r).traceScope(()=>i)}get(){return this.item}};Me.TraceableImpl=Ze});var Vt=s(Te=>{"use strict";Object.defineProperty(Te,"__esModule",{value:!0});Te.EmittableMetric=void 0;var ui=we(),Xe=class{name;unit;constructor(e,r){this.name=e,this.unit=r}withValue(e){return{name:this.name,unit:this.unit,emissionTimestamp:Date.now(),value:e,_tag:ui.MetricValueTag}}};Te.EmittableMetric=Xe});var $t=s(te=>{"use strict";Object.defineProperty(te,"__esModule",{value:!0});te.ResultMetric=te.Metric=void 0;var oe=we(),ke=class{_tag;constructor(e=oe.IMetricTag){this._tag=e}},Se=class t extends ke{name;parent;count;time;static DELIM=".";constructor(e,r=void 0,i=new oe.EmittableMetric(t.join(e,"count"),oe.Unit.COUNT),n=new oe.EmittableMetric(t.join(e,"time"),oe.Unit.MILLISECONDS)){super(),this.name=e,this.parent=r,this.count=i,this.time=n}child(e){let r=t.join(this.name,e);return new t(r,this)}asResult(){return Ee.from(this)}static join(...e){return e.join(t.DELIM)}static fromName(e){return new t(e)}};te.Metric=Se;var Ee=class t extends Se{name;parent;failure;success;warn;constructor(e,r=void 0,i,n,a){super(e,r),this.name=e,this.parent=r,this.failure=i,this.success=n,this.warn=a}static from(e){let r=e.child("failure"),i=e.child("success"),n=e.child("warn");return new t(e.name,e.parent,r,i,n)}};te.ResultMetric=Ee});var Gt=s(re=>{"use strict";Object.defineProperty(re,"__esModule",{value:!0});re.MetricsTrace=re.isMetricsTraceSupplier=void 0;var G=u(),li=t=>(0,G.isMetricValue)(t)||(0,G.isIMetric)(t)||Array.isArray(t)&&t.every(e=>(0,G.isMetricValue)(e)||(0,G.isIMetric)(e));re.isMetricsTraceSupplier=li;var et=class t{metricConsumer;activeTraces;completedTraces;constructor(e,r=new Map,i=new Set){this.metricConsumer=e,this.activeTraces=r,this.completedTraces=i}traceScope(e){let r=Date.now(),i=(Array.isArray(e)?e:[e]).filter(G.isIMetric),n=new Map(i.map(a=>[a,r]));return new t(this.metricConsumer,n)}trace(e){if(!e||typeof e=="string")return this;let r=Date.now(),i=Array.isArray(e)?e:[e],n=i.filter(G.isMetricValue),a=i.filter(G.isIMetric),o=a.filter(f=>!this.activeTraces.has(f)),d=a.filter(f=>this.activeTraces.has(f)&&!this.completedTraces.has(f)),v=d.flatMap(f=>[f.count.withValue(1),f.time.withValue(r-this.activeTraces.get(f))]),h=[...n,...v];h.length>0&&this.metricConsumer(h);let k=new Map([...this.activeTraces,...o.map(f=>[f,r])]),B=new Set([...this.completedTraces,...d]);return new t(this.metricConsumer,k,B)}};re.MetricsTrace=et});var we=s(l=>{"use strict";var di=l&&l.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,n)}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),tt=l&&l.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&di(e,t,r)};Object.defineProperty(l,"__esModule",{value:!0});l.isIMetric=l.IMetricTag=l.isMetricValue=l.MetricValueTag=l.Unit=void 0;var Kt=u(),Yt;(function(t){t.COUNT="COUNT",t.MILLISECONDS="MILLISECONDS"})(Yt||(l.Unit=Yt={}));l.MetricValueTag="MetricValue";var fi=t=>(0,Kt.isTagged)(t,l.MetricValueTag);l.isMetricValue=fi;l.IMetricTag="IMetric";var hi=t=>(0,Kt.isTagged)(t,l.IMetricTag);l.isIMetric=hi;tt(Vt(),l);tt($t(),l);tt(Gt(),l)});var zt=s(Re=>{"use strict";Object.defineProperty(Re,"__esModule",{value:!0});Re.ANSI=void 0;Re.ANSI={RESET:"\x1B[0m",BOLD:"\x1B[1m",DIM:"\x1B[2m",RED:"\x1B[31m",GREEN:"\x1B[32m",YELLOW:"\x1B[33m",BLUE:"\x1B[34m",MAGENTA:"\x1B[35m",CYAN:"\x1B[36m",WHITE:"\x1B[37m",BRIGHT_RED:"\x1B[91m",BRIGHT_YELLOW:"\x1B[93m",GRAY:"\x1B[90m"}});var Qt=s(N=>{"use strict";Object.defineProperty(N,"__esModule",{value:!0});N.isLogLevel=N.logLevelOrder=N.LogLevel=void 0;var Y;(function(t){t.UNKNOWN="UNKNOWN",t.INFO="INFO",t.WARN="WARN",t.DEBUG="DEBUG",t.ERROR="ERROR",t.SYS="SYS"})(Y||(N.LogLevel=Y={}));N.logLevelOrder=[Y.DEBUG,Y.INFO,Y.WARN,Y.ERROR,Y.SYS];var gi=t=>typeof t=="string"&&N.logLevelOrder.some(e=>e===t);N.isLogLevel=gi});var Xt=s(Zt=>{"use strict";Object.defineProperty(Zt,"__esModule",{value:!0})});var kt=s(Pe=>{"use strict";Object.defineProperty(Pe,"__esModule",{value:!0});Pe.PrettyJsonConsoleLogger=void 0;var g=je(),rt=class{log(e,...r){let i=JSON.stringify({level:e,trace:r},null,4),n=`${this.getStyle(e)}${i}${g.ANSI.RESET} +`;this.getStream(e)(n)}getStream(e){return e===g.LogLevel.ERROR?console.error:console.log}getStyle(e){switch(e){case g.LogLevel.UNKNOWN:case g.LogLevel.INFO:return`${g.ANSI.MAGENTA}`;case g.LogLevel.DEBUG:return`${g.ANSI.CYAN}`;case g.LogLevel.WARN:return`${g.ANSI.BRIGHT_YELLOW}`;case g.LogLevel.ERROR:return`${g.ANSI.BRIGHT_RED}`;case g.LogLevel.SYS:return`${g.ANSI.DIM}${g.ANSI.BLUE}`}}};Pe.PrettyJsonConsoleLogger=rt});var tr=s(Le=>{"use strict";Object.defineProperty(Le,"__esModule",{value:!0});Le.LogTrace=void 0;var er=u(),p=je(),it=class t{logger;traces;defaultLevel;allowedLevels;constructor(e=new p.PrettyJsonConsoleLogger,r=[pi],i=p.LogLevel.INFO,n=mi){this.logger=e,this.traces=r,this.defaultLevel=i,this.allowedLevels=n}traceScope(e){return new t(this.logger,this.traces.concat(e),this.defaultLevel,this.allowedLevels)}trace(e){let{traces:r,level:i}=this.foldTraces(this.traces.concat(e));if(!this.allowedLevels().has(i))return;let n=i===p.LogLevel.UNKNOWN?this.defaultLevel:i;this.logger.log(n,...r)}foldTraces(e){let r=e.map(o=>typeof o=="function"?o():o),i=r.filter(o=>(0,p.isLogLevel)(o)).reduce((o,d)=>Math.max(p.logLevelOrder.indexOf(d),o),-1),n=p.logLevelOrder[i]??p.LogLevel.UNKNOWN,a=r.filter(o=>!(0,p.isLogLevel)(o)).map(o=>typeof o=="object"?`TracedException.Name = ${o.name}, TracedException.Message = ${o.message}, TracedException.Stack = ${o.stack}`:o);return{level:n,traces:a}}};Le.LogTrace=it;var pi=()=>`TimeStamp = ${new Date().toISOString()}`,vi=(0,er.memoize)(t=>new Set([p.LogLevel.UNKNOWN,...t?[p.LogLevel.DEBUG]:[],p.LogLevel.INFO,p.LogLevel.WARN,p.LogLevel.ERROR,p.LogLevel.SYS])),mi=()=>vi((0,er.isDebug)())});var je=s(y=>{"use strict";var bi=y&&y.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,n)}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),ae=y&&y.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&bi(e,t,r)};Object.defineProperty(y,"__esModule",{value:!0});ae(zt(),y);ae(Qt(),y);ae(Xt(),y);ae(kt(),y);ae(tr(),y)});var ir=s(R=>{"use strict";Object.defineProperty(R,"__esModule",{value:!0});R.LogMetricTraceable=R.LogMetricTrace=R.EmbeddedMetricsTraceable=R.LogTraceable=void 0;var A=ot(),ce=class t extends A.TraceableImpl{static LogTrace=new A.LogTrace;static of(e){return new t(e,t.LogTrace)}};R.LogTraceable=ce;var rr=t=>e=>{e.length!==0&&t.traceScope(A.LogLevel.SYS).trace(`Metrics = ${JSON.stringify(e)}`)},nt=class t extends A.TraceableImpl{static MetricsTrace=new A.MetricsTrace(rr(ce.LogTrace));static of(e,r=t.MetricsTrace){return new t(e,r)}};R.EmbeddedMetricsTraceable=nt;var qe=class t{logTrace;metricsTrace;constructor(e,r){this.logTrace=e,this.metricsTrace=r}traceScope(e){return(0,A.isMetricsTraceSupplier)(e)?new t(this.logTrace,this.metricsTrace.traceScope(e)):new t(this.logTrace.traceScope(e),this.metricsTrace)}trace(e){return(0,A.isMetricsTraceSupplier)(e)?(this.metricsTrace.trace(e),this):(this.logTrace.trace(e),this)}};R.LogMetricTrace=qe;var st=class t extends A.TraceableImpl{static ofLogTraceable(e){let r=new A.MetricsTrace(rr(e.trace));return new t(e.get(),new qe(e.trace,r))}static of(e){let r=ce.of(e);return t.ofLogTraceable(r)}};R.LogMetricTraceable=st});var nr=s(Ne=>{"use strict";Object.defineProperty(Ne,"__esModule",{value:!0});Ne.TraceUtil=void 0;var at=u(),ct=class t{static promiseify(e){return r=>r.flatMapAsync(async i=>i.move(await i.get()).map(e)).get()}static traceResultingEither(e,r=!1){return i=>(e&&i.trace.trace(i.get().fold(n=>r?e.warn:e.failure,n=>e.success)),i.traceScope(n=>n.get().fold(a=>r?at.LogLevel.WARN:at.LogLevel.ERROR,a=>at.LogLevel.INFO)))}static withTrace(e){return r=>r.traceScope(()=>e)}static withMetricTrace(e){return t.withTrace(e)}static withFunctionTrace(e){return t.withTrace(`fn.${e.name}`)}static withClassTrace(e){return t.withTrace(`class.${e.constructor.name}`)}};Ne.TraceUtil=ct});var ot=s(O=>{"use strict";var _i=O&&O.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,n)}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),ue=O&&O.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&_i(e,t,r)};Object.defineProperty(O,"__esModule",{value:!0});ue(Jt(),O);ue(we(),O);ue(je(),O);ue(ir(),O);ue(nr(),O)});var sr=s(M=>{"use strict";Object.defineProperty(M,"__esModule",{value:!0});M.getStdoutMany=M.getStdout=M.CmdMetric=void 0;var H=u(),yi=require("node:child_process");M.CmdMetric=H.Metric.fromName("Exec").asResult();var Oi=(t,e={streamTraceable:[]})=>t.flatMap(H.TraceUtil.withFunctionTrace(M.getStdout)).flatMap(r=>r.traceScope(()=>`Command = ${r.get()}`)).map(r=>{let i=r.get(),n=typeof i=="string"?i:i.join(" "),a=e.clearEnv?e.env:{...process.env,...e.env};return H.Either.fromFailableAsync(new Promise((o,d)=>{let v=(0,yi.exec)(n,{env:a}),h="";v.stdout?.on("data",B=>{let f=B.toString();h+=f,e.streamTraceable?.includes("stdout")&&r.trace.trace(f)});let k="";v.stderr?.on("data",B=>{let f=B.toString();h+=f,e.streamTraceable?.includes("stderr")&&r.trace.trace(f)}),v.on("exit",B=>{B===0?o({stdout:h,stderr:k}):d(new Error(`exited with non-zero code: ${B}. ${k}`))})}))}).map(H.TraceUtil.promiseify(r=>r.get().mapRight(({stderr:i,stdout:n})=>(i&&r.trace.traceScope(H.LogLevel.DEBUG).trace(`StdErr = ${i}`),n)))).peek(H.TraceUtil.promiseify(H.TraceUtil.traceResultingEither(M.CmdMetric))).get();M.getStdout=Oi;var Mi=(t,e={streamTraceable:[]})=>t.coExtend(r=>r.get()).reduce(async(r,i)=>(await r).joinRightAsync(()=>i.map(a=>(0,M.getStdout)(a,e)).get(),(a,o)=>o.concat(a)),Promise.resolve(H.Either.right([])));M.getStdoutMany=Mi});var or=s(P=>{"use strict";Object.defineProperty(P,"__esModule",{value:!0});P.getRequiredEnvVars=P.getRequiredEnv=P.getEnv=void 0;var ut=u(),Ti=t=>ut.Optional.from(process.env[t]);P.getEnv=Ti;var wi=t=>ut.Either.fromFailable(()=>(0,P.getEnv)(t).get()).mapLeft(()=>new Error(`environment variable "${t}" is required D:`));P.getRequiredEnv=wi;var Si=t=>{let e=ut.Either.right({}),r=(i,n,a)=>({...i,[n]:a});return t.reduce((i,n)=>i.joinRight((0,P.getRequiredEnv)(n),(a,o)=>r(o,n,a)),e)};P.getRequiredEnvVars=Si});var cr=s(K=>{"use strict";Object.defineProperty(K,"__esModule",{value:!0});K.validateExecutionEntries=K.validateIdentifier=void 0;var ar=u(),Ei=t=>/^[a-zA-Z0-9_\-:. \/]+$/.test(t)&&!t.includes("..");K.validateIdentifier=Ei;var Ri=t=>{let e=Object.entries(t).filter(r=>!r.every(i=>typeof i=="string"&&(0,K.validateIdentifier)(i)));return e.length>0?ar.Either.left(e):ar.Either.right(t)};K.validateExecutionEntries=Ri});var ur=s(T=>{"use strict";Object.defineProperty(T,"__esModule",{value:!0});T.argv=T.getArg=T.isArgKey=void 0;var z=u(),Pi=t=>t.startsWith("--");T.isArgKey=Pi;var ji=(t,e,r)=>{let i=z.Optional.from(e.findIndex(n=>(0,T.isArgKey)(n)&&n.split("=")[0]===t)).filter(n=>n>=0&&nz.Optional.from(e.at(n)).map(a=>a.includes("=")?a.split("=")[1]:e.at(n+1))).filter(n=>!(0,T.isArgKey)(n)).map(n=>r.present(n)).orSome(()=>r.unspecified).map(n=>z.Either.right(n)).get():z.Optional.from(r.absent).map(n=>z.Either.right(n)).orSome(()=>z.Either.left(new Error(`arg ${t} is not present in arguments list and does not have an 'absent' value`))).get()};T.getArg=ji;var Li=(t,e,r=process.argv.slice(2))=>{let i={present:o=>o},n=o=>{let d=e?.[o]??i;return(0,T.getArg)(o,r,d).mapRight(v=>[o,v])};return t.map(n).reduce((o,d)=>o.flatMap(v=>d.mapRight(([h,k])=>({...v,[h]:k}))),z.Either.right({})).mapRight(o=>o)};T.argv=Li});var lr=s(j=>{"use strict";Object.defineProperty(j,"__esModule",{value:!0});j.Signals=j.SigTermMetric=j.SigIntMetric=void 0;var I=u();j.SigIntMetric=I.Metric.fromName("SigInt").asResult();j.SigTermMetric=I.Metric.fromName("SigTerm").asResult();var lt=class{static async awaitClose(e){let r=I.Either.right(void 0);return new Promise(i=>{let n=d=>v=>e.flatMap(I.TraceUtil.withMetricTrace(d)).peek(h=>h.trace.trace("closing")).move(I.Optional.from(v).map(h=>I.Either.left(h)).orSome(()=>r).get()).flatMap(I.TraceUtil.traceResultingEither(d)).map(h=>i(h.get())).peek(h=>h.trace.trace("finished")).get(),a=n(j.SigIntMetric),o=n(j.SigTermMetric);process.on("SIGINT",()=>e.flatMap(I.TraceUtil.withTrace("SIGINT")).get().close(a)),process.on("SIGTERM",()=>e.flatMap(I.TraceUtil.withTrace("SIGTERM")).get().close(o))})}};j.Signals=lt});var dr=s(w=>{"use strict";var qi=w&&w.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,n)}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),le=w&&w.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&qi(e,t,r)};Object.defineProperty(w,"__esModule",{value:!0});le(sr(),w);le(or(),w);le(cr(),w);le(ur(),w);le(lr(),w)});var hr=s(fr=>{"use strict";Object.defineProperty(fr,"__esModule",{value:!0})});var gr=s(Ae=>{"use strict";Object.defineProperty(Ae,"__esModule",{value:!0});Ae.HttpStatusCodes=void 0;Ae.HttpStatusCodes={100:"Continue",101:"Switching Protocols",102:"Processing (WebDAV)",200:"OK",201:"Created",202:"Accepted",203:"Non-Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",207:"Multi-Status (WebDAV)",208:"Already Reported (WebDAV)",226:"IM Used",300:"Multiple Choices",301:"Moved Permanently",302:"Found",303:"See Other",304:"Not Modified",305:"Use Proxy",306:"(Unused)",307:"Temporary Redirect",308:"Permanent Redirect (experimental)",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Request Entity Too Large",414:"Request-URI Too Long",415:"Unsupported Media Type",416:"Requested Range Not Satisfiable",417:"Expectation Failed",418:"I'm a teapot (RFC 2324)",420:"Enhance Your Calm (Twitter)",422:"Unprocessable Entity (WebDAV)",423:"Locked (WebDAV)",424:"Failed Dependency (WebDAV)",425:"Reserved for WebDAV",426:"Upgrade Required",428:"Precondition Required",429:"Too Many Requests",431:"Request Header Fields Too Large",444:"No Response (Nginx)",449:"Retry With (Microsoft)",450:"Blocked by Windows Parental Controls (Microsoft)",451:"Unavailable For Legal Reasons",499:"Client Closed Request (Nginx)",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates (Experimental)",507:"Insufficient Storage (WebDAV)",508:"Loop Detected (WebDAV)",509:"Bandwidth Limit Exceeded (Apache)",510:"Not Extended",511:"Network Authentication Required",598:"Network read timeout error",599:"Network connect timeout error"}});var vr=s(pr=>{"use strict";Object.defineProperty(pr,"__esModule",{value:!0})});var mr=s(D=>{"use strict";var Ni=D&&D.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,n)}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),dt=D&&D.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&Ni(e,t,r)};Object.defineProperty(D,"__esModule",{value:!0});dt(hr(),D);dt(gr(),D);dt(vr(),D)});var br=s(U=>{"use strict";Object.defineProperty(U,"__esModule",{value:!0});U.JsonResponse=U.PenguenoResponse=U.getResponseMetrics=void 0;var de=u(),Ai=(t,e)=>{let r={...t.getResponseHeaders(),...e};return r["Content-Type"]=(r["Content-Type"]??"text/plain")+"; charset=utf-8",r},Ii=[0,1,2,3,4,5].map(t=>de.Metric.fromName(`response.${t}xx`).asResult()),Di=(t,e)=>{let r=Math.floor(t/100);return Ii.flatMap((i,n)=>de.Optional.from(n).filter(a=>a===r).map(()=>[i.count.withValue(1)]).flatMap(a=>de.Optional.from(e).map(o=>a.concat(i.time.withValue(o))).orSome(()=>a)).orSome(()=>[i.count.withValue(0)]).get())};U.getResponseMetrics=Di;var Ie=class{_body;statusText;status;headers;constructor(e,r,i){this._body=r,this.headers=Ai(e.get(),i?.headers??{}),this.status=i.status,this.statusText=i.statusText??de.HttpStatusCodes[this.status],e.trace.trace((0,U.getResponseMetrics)(i.status,e.get().elapsedTimeMs()))}body(){return this._body}};U.PenguenoResponse=Ie;var ft=class extends Ie{constructor(e,r,i){let n={...i,headers:{...i.headers,"Content-Type":"application/json"}};if((0,de.isEither)(r)){super(e,JSON.stringify(r.fold(a=>({error:a,ok:void 0}),a=>({ok:a}))),n);return}super(e,JSON.stringify(Math.floor(n.status/100)>4?{error:r}:{ok:r}),n)}};U.JsonResponse=ft});var _r=s(Q=>{"use strict";var Ui=Q&&Q.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,n)}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),Ci=Q&&Q.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&Ui(e,t,r)};Object.defineProperty(Q,"__esModule",{value:!0});Ci(br(),Q)});var Or=s(De=>{"use strict";Object.defineProperty(De,"__esModule",{value:!0});De.PenguenoRequest=void 0;var yr=["hewwo :D","hiya cutie","boop!","sending virtual hugs!","stay pawsitive"],Bi=()=>yr[Math.floor(Math.random()*yr.length)],ht=class t{req;id;at;constructor(e,r,i){this.req=e,this.id=r,this.at=i}elapsedTimeMs(e=()=>Date.now()){return e()-this.at.getTime()}getResponseHeaders(){let e=this.id,r=this.at.getTime(),i=Date.now(),n=this.elapsedTimeMs(()=>i),a=Bi();return Object.entries({RequestId:e,RequestReceivedUnix:r,RequestHandleUnix:i,DeltaUnix:n,Hai:a}).reduce((o,[d,v])=>({...o,[d]:v.toString()}),{})}static from(e){let r=crypto.randomUUID();return e.bimap(i=>{let n=i.get(),a=new URL(n.url),{pathname:o}=a,d=`RequestId = ${r}, Method = ${n.method}, Path = ${o}`;return{item:new t(n,r,new Date),trace:d}})}};De.PenguenoRequest=ht});var Mr=s(Z=>{"use strict";var Hi=Z&&Z.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,n)}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),xi=Z&&Z.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&Hi(e,t,r)};Object.defineProperty(Z,"__esModule",{value:!0});xi(Or(),Z)});var Sr=s(x=>{"use strict";Object.defineProperty(x,"__esModule",{value:!0});x.HealthCheckActivityImpl=x.HealthCheckOutput=x.HealthCheckInput=void 0;var X=u(),gt;(function(t){t[t.CHECK=0]="CHECK"})(gt||(x.HealthCheckInput=gt={}));var Tr;(function(t){t[t.YAASSSLAYQUEEN=0]="YAASSSLAYQUEEN"})(Tr||(x.HealthCheckOutput=Tr={}));var wr=X.Metric.fromName("Health").asResult(),pt=class{check;constructor(e){this.check=e}checkHealth(e){return e.flatMap(X.TraceUtil.withFunctionTrace(this.checkHealth)).flatMap(X.TraceUtil.withMetricTrace(wr)).flatMap(r=>r.move(gt.CHECK).map(i=>this.check(i))).peek(X.TraceUtil.promiseify(X.TraceUtil.traceResultingEither(wr))).map(X.TraceUtil.promiseify(r=>{let{status:i,message:n}=r.get().fold(()=>({status:500,message:"err"}),()=>({status:200,message:"ok"}));return new X.JsonResponse(e,n,{status:i})})).get()}};x.HealthCheckActivityImpl=pt});var Rr=s(Ue=>{"use strict";Object.defineProperty(Ue,"__esModule",{value:!0});Ue.FourOhFourActivityImpl=void 0;var Wi=u(),Er=["D: meow-t found! your api call ran away!","404-bidden! but like...in a cute way >:3 !",":< your data went on a paw-sible vacation!","uwu~ not found, but found our hearts instead!"],Fi=()=>Er[Math.floor(Math.random()*Er.length)],vt=class{fourOhFour(e){return e.move(new Wi.JsonResponse(e,Fi(),{status:404})).map(r=>Promise.resolve(r.get())).get()}};Ue.FourOhFourActivityImpl=vt});var jr=s(W=>{"use strict";var Ji=W&&W.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,n)}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),Pr=W&&W.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&Ji(e,t,r)};Object.defineProperty(W,"__esModule",{value:!0});Pr(Sr(),W);Pr(Rr(),W)});var Lr=s(he=>{"use strict";Object.defineProperty(he,"__esModule",{value:!0});he.requireMethod=void 0;var fe=u(),Vi=t=>e=>e.flatMap(fe.TraceUtil.withFunctionTrace(he.requireMethod)).map(r=>{let{req:{method:i}}=r.get();if(!t.includes(i)){let n="that's not how you pet me (\u22DF\uFE4F\u22DE)~";return r.trace.traceScope(fe.LogLevel.WARN).trace(n),fe.Either.left(new fe.PenguenoError(n,405))}return fe.Either.right(i)}).get();he.requireMethod=Vi});var Nr=s(ge=>{"use strict";Object.defineProperty(ge,"__esModule",{value:!0});ge.jsonModel=void 0;var C=u(),qr=C.Metric.fromName("JsonParse").asResult(),$i=t=>e=>e.flatMap(C.TraceUtil.withFunctionTrace(ge.jsonModel)).flatMap(C.TraceUtil.withMetricTrace(qr)).map(r=>C.Either.fromFailableAsync(r.get().req.json()).then(i=>i.mapLeft(n=>(r.trace.traceScope(C.LogLevel.WARN).trace(n),new C.PenguenoError("seems to be invalid JSON (>//<) can you fix?",400))))).flatMapAsync(C.TraceUtil.promiseify(C.TraceUtil.traceResultingEither(qr))).map(C.TraceUtil.promiseify(r=>r.get().mapRight(i=>r.move(i)).flatMap(t))).get();ge.jsonModel=$i});var Ir=s(b=>{"use strict";var Gi=b&&b.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,n)}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),Ar=b&&b.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&Gi(e,t,r)};Object.defineProperty(b,"__esModule",{value:!0});b.PenguenoError=b.ErrorSource=void 0;var Xn=u(),Ce;(function(t){t.USER="WARN",t.SYSTEM="ERROR"})(Ce||(b.ErrorSource=Ce={}));var mt=class extends Error{message;status;source;constructor(e,r){super(e),this.message=e,this.status=r,this.source=Math.floor(r/100)===4?Ce.USER:Ce.SYSTEM}};b.PenguenoError=mt;Ar(Lr(),b);Ar(Nr(),b)});var Dr=s(S=>{"use strict";var Yi=S&&S.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,n)}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),pe=S&&S.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&Yi(e,t,r)};Object.defineProperty(S,"__esModule",{value:!0});pe(mr(),S);pe(_r(),S);pe(Mr(),S);pe(jr(),S);pe(Ir(),S)});var u=s(E=>{"use strict";var Ki=E&&E.__createBinding||(Object.create?function(t,e,r,i){i===void 0&&(i=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,n)}:function(t,e,r,i){i===void 0&&(i=r),t[i]=e[r]}),ve=E&&E.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&Ki(e,t,r)};Object.defineProperty(E,"__esModule",{value:!0});ve(Et(),E);ve(Je(),E);ve(ot(),E);ve(dr(),E);ve(Dr(),E)});var bt=We(u(),1),zi=["fetch_code","ci_pipeline","build_docker_image.js","ansible_playbook.js","checkout_ci.js","npm_publish.js"],Qi=t=>typeof t=="string"&&zi.includes(t),Ur=t=>!!((0,bt.isObject)(t)&&"arguments"in t&&(0,bt.isObject)(t.arguments)&&"type"in t&&Qi(t.type)&&t);var yt=We(u(),1);var _t=class{stages=[];addStage(e){return this.stages.push(e),this}build(){return new He(this.stages)}},Be=class extends _t{remoteUrl;refname;constructor(e=process.env.remote,r=process.env.rev,i=process.env.refname){super(),this.remoteUrl=e,this.refname=i,this.addStage({parallelJobs:[{type:"fetch_code",arguments:{remoteUrl:e,checkout:r,path:this.getSourceDestination()}}]})}getSourceDestination(){return this.remoteUrl.replace(".git","").split("/").at(-1)??"src"}getBranch(){return this.refname.split("refs/heads/").at(1)}};var xe=We(u(),1);var He=class t{serialJobs;constructor(e){this.serialJobs=e}serialize(){return JSON.stringify({serialJobs:this.serialJobs})}static from(e){return xe.Either.fromFailable(()=>JSON.parse(e)).flatMap(r=>Cr(r)?xe.Either.right(r):xe.Either.left(new Error("oh noes D: its a bad pipewine :(("))).mapRight(r=>new t(r.serialJobs))}};var Zi=t=>(0,yt.isObject)(t)&&"parallelJobs"in t&&Array.isArray(t.parallelJobs)&&t.parallelJobs.every(e=>Ur(e)),Cr=t=>(0,yt.isObject)(t)&&"serialJobs"in t&&Array.isArray(t.serialJobs)&&t.serialJobs.every(e=>Zi(e));var Xi="oci.liz.coffee",ki="emprespresso",Br="wwwgit",en="ssh://src.liz.coffee:2222",tn=()=>{let t=new Be,e=t.getBranch();if(!e)return t.build();let i={type:"build_docker_image.js",arguments:{...{context:t.getSourceDestination(),registry:Xi,namespace:ki,imageTag:e},repository:Br,buildTarget:Br,dockerfile:"Dockerfile"}};return t.addStage({parallelJobs:[i]}),e==="release"&&[{type:"fetch_code",arguments:{remoteUrl:`${en}/infra`,checkout:"main",path:"infra"}},{type:"ansible_playbook.js",arguments:{path:"infra",playbooks:"playbooks/src.yml"}}].forEach(d=>t.addStage({parallelJobs:[d]})),t.build()},rn=()=>{let t=tn().serialize();process.stdout.write(t)};rn(); diff --git a/.ci/ci.json b/.ci/ci.json new file mode 100644 index 0000000..e10df80 --- /dev/null +++ b/.ci/ci.json @@ -0,0 +1,3 @@ +{ + "workflow": ".ci/ci.js" +} diff --git a/.ci/ci.ts b/.ci/ci.ts new file mode 100644 index 0000000..991ae45 --- /dev/null +++ b/.ci/ci.ts @@ -0,0 +1,75 @@ +#!/usr/bin/env node + +import { + AnsiblePlaybookJob, + BuildDockerImageJob, + DefaultGitHookPipelineBuilder, + FetchCodeJob, + Job, +} from '@emprespresso/ci_model'; +import { join } from 'path'; + +const REGISTRY = 'oci.liz.coffee'; +const NAMESPACE = 'emprespresso'; +const IMG = 'wwwgit'; +const REMOTE = 'ssh://src.liz.coffee:2222'; + +const getPipeline = () => { + const gitHookPipeline = new DefaultGitHookPipelineBuilder(); + const branch = gitHookPipeline.getBranch(); + if (!branch) return gitHookPipeline.build(); + + const commonBuildArgs = { + context: gitHookPipeline.getSourceDestination(), + registry: REGISTRY, + namespace: NAMESPACE, + imageTag: branch, + }; + + const buildGit: BuildDockerImageJob = { + type: 'build_docker_image.js', + arguments: { + ...commonBuildArgs, + repository: IMG, + buildTarget: IMG, + dockerfile: 'Dockerfile', + }, + }; + gitHookPipeline.addStage({ + parallelJobs: [buildGit], + }); + + const isRelease = branch === 'release'; + if (!isRelease) { + return gitHookPipeline.build(); + } + + const fetchAnsibleCode: FetchCodeJob = { + type: 'fetch_code', + arguments: { + remoteUrl: `${REMOTE}/infra`, + checkout: 'main', + path: 'infra', + }, + }; + const thenDeploy: AnsiblePlaybookJob = { + type: 'ansible_playbook.js', + arguments: { + path: 'infra', + playbooks: 'playbooks/src.yml', + }, + }; + [fetchAnsibleCode, thenDeploy].forEach((deploymentStage) => + gitHookPipeline.addStage({ parallelJobs: [deploymentStage] }), + ); + + return gitHookPipeline.build(); +}; + +const main = () => { + const data = getPipeline().serialize(); + process.stdout.write(data); +}; + +main(); + diff --git a/.ci/package-lock.json b/.ci/package-lock.json new file mode 100644 index 0000000..89f8713 --- /dev/null +++ b/.ci/package-lock.json @@ -0,0 +1,532 @@ +{ + "name": ".ci", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@emprespresso/ci_model": "^0.1.0" + }, + "devDependencies": { + "@types/node": "^24.1.0", + "esbuild": "0.25.5", + "typescript": "^5.8.3" + } + }, + "node_modules/@emprespresso/ci_model": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@emprespresso/ci_model/-/ci_model-0.1.0.tgz", + "integrity": "sha512-Ig1F61q+KiMUBAiAP/rp8a2+WM3RKuz1+qWunHljS2KP28du4kCidHH+8Z/I9RHEi/5gPBTppIL2ZmXlccsRPg==", + "dependencies": { + "@emprespresso/pengueno": "^0.0.6" + } + }, + "node_modules/@emprespresso/pengueno": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@emprespresso/pengueno/-/pengueno-0.0.6.tgz", + "integrity": "sha512-QjyNXJPFp6OlOuk6cH/0yzdFznItofqhB1wF75k/Len5A0BsqvuE1QGU9aZ7AkujGkIpbv21Vm6K21/bmk0S2A==", + "license": "MIT", + "engines": { + "node": ">=22.16.0", + "npm": ">=10.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", + "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", + "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", + "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", + "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", + "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", + "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", + "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", + "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", + "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", + "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", + "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", + "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", + "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", + "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", + "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", + "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", + "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", + "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", + "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", + "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", + "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", + "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", + "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", + "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", + "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@types/node": { + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz", + "integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.8.0" + } + }, + "node_modules/esbuild": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", + "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.5", + "@esbuild/android-arm": "0.25.5", + "@esbuild/android-arm64": "0.25.5", + "@esbuild/android-x64": "0.25.5", + "@esbuild/darwin-arm64": "0.25.5", + "@esbuild/darwin-x64": "0.25.5", + "@esbuild/freebsd-arm64": "0.25.5", + "@esbuild/freebsd-x64": "0.25.5", + "@esbuild/linux-arm": "0.25.5", + "@esbuild/linux-arm64": "0.25.5", + "@esbuild/linux-ia32": "0.25.5", + "@esbuild/linux-loong64": "0.25.5", + "@esbuild/linux-mips64el": "0.25.5", + "@esbuild/linux-ppc64": "0.25.5", + "@esbuild/linux-riscv64": "0.25.5", + "@esbuild/linux-s390x": "0.25.5", + "@esbuild/linux-x64": "0.25.5", + "@esbuild/netbsd-arm64": "0.25.5", + "@esbuild/netbsd-x64": "0.25.5", + "@esbuild/openbsd-arm64": "0.25.5", + "@esbuild/openbsd-x64": "0.25.5", + "@esbuild/sunos-x64": "0.25.5", + "@esbuild/win32-arm64": "0.25.5", + "@esbuild/win32-ia32": "0.25.5", + "@esbuild/win32-x64": "0.25.5" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/.ci/package.json b/.ci/package.json new file mode 100644 index 0000000..03171d1 --- /dev/null +++ b/.ci/package.json @@ -0,0 +1,18 @@ +{ + "scripts": { + "build": "tsc && node bundle.js", + "clean": "rm -rf dist ci.cjs" + }, + "dependencies": { + "@emprespresso/ci_model": "^0.1.0" + }, + "devDependencies": { + "@types/node": "^24.1.0", + "esbuild": "0.25.5", + "typescript": "^5.8.3" + }, + "files": [ + "dist/**/*", + "package.json" + ] +} diff --git a/.ci/tsconfig.json b/.ci/tsconfig.json new file mode 100644 index 0000000..51aeb50 --- /dev/null +++ b/.ci/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "baseUrl": ".", + "outDir": "./dist", + "declaration": true, + "moduleResolution": "node", + "strict": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "lib": ["ES2022"] + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"], + "references": [] +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2cec7de --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +**/node_modules +.git/ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a99edb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +**/dist +**/node_modules diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2d73b0a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,64 @@ +FROM debian:stable-slim AS build_stage + +ARG CGIT_VERSION="master" + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + git \ + liblua5.1-dev \ + zlib1g-dev \ + libssl-dev \ + gettext \ + python3 \ + python3-docutils \ + python3-markdown \ + python3-pygments \ + ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /opt +RUN git clone https://git.zx2c4.com/cgit +WORKDIR /opt/cgit +RUN git checkout ${CGIT_VERSION} \ + && git submodule init \ + && git submodule update + +COPY cgit.conf . + +RUN make -j7 && make install + +FROM debian:stable-slim AS wwwgit + +RUN apt-get update && apt-get install -y --no-install-recommends \ + nginx-light \ + fcgiwrap \ + git \ + gettext-base \ + python3 \ + python3-docutils \ + python3-markdown \ + python3-pygments \ + tini \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=build_stage /var/www/html/cgit /var/www/html/cgit + +RUN mkdir -p /var/lib/git/repositories \ + && chown -R www-data:www-data /var/www/html/cgit \ + && chown -R www-data:www-data /var/lib/git + +RUN rm /etc/nginx/sites-enabled/default + +COPY cgit.nginx.conf /etc/nginx/sites-available/cgit.conf +RUN ln -s /etc/nginx/sites-available/cgit.conf /etc/nginx/sites-enabled/cgit.conf + +COPY cgitrc /var/www/html/cgit/cgitrc + +COPY entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh + +RUN mkdir /run/sock +RUN chown -R www-data:www-data /run/sock + +EXPOSE 80 +ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/entrypoint.sh"] diff --git a/cgit.conf b/cgit.conf new file mode 100644 index 0000000..b5f5763 --- /dev/null +++ b/cgit.conf @@ -0,0 +1,6 @@ +CGIT_SCRIPT_PATH = /var/www/html/cgit/cgi +CGIT_CONFIG = /var/www/html/cgit/cgitrc +CACHE_ROOT = /var/www/html/cgit/cache +prefix = /var/www/html/cgit +libdir = $(prefix) +filterdir = $(libdir)/filters diff --git a/cgit.nginx.conf b/cgit.nginx.conf new file mode 100644 index 0000000..f071c8d --- /dev/null +++ b/cgit.nginx.conf @@ -0,0 +1,23 @@ +server { + listen 80; + listen [::]:80; + + server_name localhost; + + root /var/www/html/cgit/cgi; + + try_files $uri @cgit; + + location @cgit { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME /var/www/html/cgit/cgi/cgit.cgi; + fastcgi_pass unix:/run/sock/fcgiwrap.socket; + fastcgi_param PATH_INFO $uri; + fastcgi_param QUERY_STRING $args; + fastcgi_param HTTP_HOST $server_name; + } + + location ~ ^/(cgit.css|cgit.png|favicon.ico|header.html|footer.html) { + root /var/www/html/cgit/static; + } +} diff --git a/cgitrc b/cgitrc new file mode 100644 index 0000000..2a80184 --- /dev/null +++ b/cgitrc @@ -0,0 +1,17 @@ +clone-url=ssh://git@src.liz.coffee:2222/$CGIT_REPO_URL +root-title=/home/liz/src +root-desc=⋆⭒˚.⋆ 🐧 <3 ⋆⭒˚.⋆ + +favicon=/favicon.ico +css=/cgit.css +logo=/cgit.png +branch-sort=age +max-stats-graph=50 +max-repo-count=100 +snapshots=tar.gz zip + +enable-http-clone=1 + +scan-path=/var/lib/git/repositories + +source-filter=/var/www/html/cgit/filters/cgit-pygments-filter.py diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..5bdcede --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +set -e + +echo "Starting fcgiwrap..." +su -l www-data -s /bin/bash -c "/usr/sbin/fcgiwrap -s unix:/run/sock/fcgiwrap.socket" & + +echo "Waiting for fcgiwrap socket to appear..." +while [ ! -S /run/sock/fcgiwrap.socket ]; do + sleep 0.1 +done +echo "fcgiwrap socket found." + +echo "Starting Nginx..." +exec nginx -g 'daemon off;' diff --git a/static/cgit.css b/static/cgit.css new file mode 100644 index 0000000..e71562c --- /dev/null +++ b/static/cgit.css @@ -0,0 +1,1078 @@ +* { + font-family: monospace; +} + +/* cgit.css */ +div#cgit { + padding: 0em; + margin: 0em; + font-family: sans-serif; + font-size: 10pt; + color: #333; + background: white; + padding: 4px; +} + +div#cgit a { + color: blue; + text-decoration: none; +} + +div#cgit a:hover { + text-decoration: underline; +} + +div#cgit table { + border-collapse: collapse; +} + +div#cgit table#header { + width: 100%; + margin-bottom: 1em; +} + +div#cgit table#header td.logo { + width: 96px; + vertical-align: top; +} + +div#cgit table#header td.main { + font-size: 250%; + padding-left: 10px; + white-space: nowrap; +} + +div#cgit table#header td.main a { + color: #000; +} + +div#cgit table#header td.form { + text-align: right; + vertical-align: bottom; + padding-right: 1em; + padding-bottom: 2px; + white-space: nowrap; +} + +div#cgit table#header td.form form, +div#cgit table#header td.form input, +div#cgit table#header td.form select { + font-size: 90%; +} + +div#cgit table#header td.sub { + color: #777; + border-top: solid 1px #ccc; + padding-left: 10px; +} + +div#cgit table.tabs { + border-bottom: solid 3px #ccc; + border-collapse: collapse; + margin-top: 2em; + margin-bottom: 0px; + width: 100%; +} + +div#cgit table.tabs td { + padding: 0px 1em; + vertical-align: bottom; +} + +div#cgit table.tabs td a { + padding: 2px 0.75em; + color: #777; + font-size: 110%; +} + +div#cgit table.tabs td a.active { + color: #000; + background-color: #ccc; +} + +div#cgit table.tabs a[href^="http://"]:after, div#cgit table.tabs a[href^="https://"]:after { + content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfgAhcJDQY+gm2TAAAAHWlUWHRDb21tZW50AAAAAABDcmVhdGVkIHdpdGggR0lNUGQuZQcAAABbSURBVAhbY2BABs4MU4CwhYHBh2Erww4wrGFQZHjI8B8IgUIscJWyDHcggltQhI4zGDCcRwhChPggHIggP1QoAVmQkSETrGoHsiAEsACtBYN0oDAMbgU6EBcAAL2eHUt4XUU4AAAAAElFTkSuQmCC); + opacity: 0.5; + margin: 0 0 0 5px; +} + +div#cgit table.tabs td.form { + text-align: right; +} + +div#cgit table.tabs td.form form { + padding-bottom: 2px; + font-size: 90%; + white-space: nowrap; +} + +div#cgit table.tabs td.form input, +div#cgit table.tabs td.form select { + font-size: 90%; +} + +div#cgit div.path { + margin: 0px; + padding: 5px 2em 2px 2em; + color: #000; + background-color: #eee; +} + +div#cgit div.content { + margin: 0px; + padding: 2em; + border-bottom: solid 3px #ccc; +} + + +div#cgit table.list { + width: 100%; + border: none; + border-collapse: collapse; +} + +div#cgit table.list tr { + background: white; +} + +div#cgit table.list tr.logheader { + background: #eee; +} + +div#cgit table.list tr:nth-child(even) { + background: #f7f7f7; +} + +div#cgit table.list tr:nth-child(odd) { + background: white; +} + +div#cgit table.list tr:hover { + background: #eee; +} + +div#cgit table.list tr.nohover { + background: white; +} + +div#cgit table.list tr.nohover:hover { + background: white; +} + +div#cgit table.list tr.nohover-highlight:hover:nth-child(even) { + background: #f7f7f7; +} + +div#cgit table.list tr.nohover-highlight:hover:nth-child(odd) { + background: white; +} + +div#cgit table.list th { + font-weight: bold; + /* color: #888; + border-top: dashed 1px #888; + border-bottom: dashed 1px #888; + */ + padding: 0.1em 0.5em 0.05em 0.5em; + vertical-align: baseline; +} + +div#cgit table.list td { + border: none; + padding: 0.1em 0.5em 0.1em 0.5em; +} + +div#cgit table.list td.commitgraph { + font-family: monospace; + white-space: pre; +} + +div#cgit table.list td.commitgraph .column1 { + color: #a00; +} + +div#cgit table.list td.commitgraph .column2 { + color: #0a0; +} + +div#cgit table.list td.commitgraph .column3 { + color: #aa0; +} + +div#cgit table.list td.commitgraph .column4 { + color: #00a; +} + +div#cgit table.list td.commitgraph .column5 { + color: #a0a; +} + +div#cgit table.list td.commitgraph .column6 { + color: #0aa; +} + +div#cgit table.list td.logsubject { + font-family: monospace; + font-weight: bold; +} + +div#cgit table.list td.logmsg { + font-family: monospace; + white-space: pre; + padding: 0 0.5em; +} + +div#cgit table.list td a { + color: black; +} + +div#cgit table.list td a.ls-dir { + font-weight: bold; + color: #00f; +} + +div#cgit table.list td a:hover { + color: #00f; +} + +div#cgit img { + border: none; +} + +div#cgit input#switch-btn { + margin: 2px 0px 0px 0px; +} + +div#cgit td#sidebar input.txt { + width: 100%; + margin: 2px 0px 0px 0px; +} + +div#cgit table#grid { + margin: 0px; +} + +div#cgit td#content { + vertical-align: top; + padding: 1em 2em 1em 1em; + border: none; +} + +div#cgit div#summary { + vertical-align: top; + margin-bottom: 1em; +} + +div#cgit table#downloads { + float: right; + border-collapse: collapse; + border: solid 1px #777; + margin-left: 0.5em; + margin-bottom: 0.5em; +} + +div#cgit table#downloads th { + background-color: #ccc; +} + +div#cgit div#blob { + border: solid 1px black; +} + +div#cgit div.error { + color: red; + font-weight: bold; + margin: 1em 2em; +} + +div#cgit a.ls-blob, div#cgit a.ls-dir, div#cgit .ls-mod { + font-family: monospace; +} + +div#cgit td.ls-size { + text-align: right; + font-family: monospace; + width: 10em; +} + +div#cgit td.ls-mode { + font-family: monospace; + width: 10em; +} + +div#cgit table.blob { + margin-top: 0.5em; + border-top: solid 1px black; +} + +div#cgit table.blob td.hashes, +div#cgit table.blob td.lines { + margin: 0; padding: 0 0 0 0.5em; + vertical-align: top; + color: black; +} + +div#cgit table.blob td.linenumbers { + margin: 0; padding: 0 0.5em 0 0.5em; + vertical-align: top; + text-align: right; + border-right: 1px solid gray; +} + +div#cgit table.blob pre { + padding: 0; margin: 0; +} + +div#cgit table.blob td.linenumbers a, +div#cgit table.ssdiff td.lineno a { + color: gray; + text-align: right; + text-decoration: none; +} + +div#cgit table.blob td.linenumbers a:hover, +div#cgit table.ssdiff td.lineno a:hover { + color: black; +} + +div#cgit table.blame td.hashes, +div#cgit table.blame td.lines, +div#cgit table.blame td.linenumbers { + padding: 0; +} + +div#cgit table.blame td.hashes div.alt, +div#cgit table.blame td.lines div.alt { + padding: 0 0.5em 0 0.5em; +} + +div#cgit table.blame td.linenumbers div.alt { + padding: 0 0.5em 0 0; +} + +div#cgit table.blame div.alt:nth-child(even) { + background: #eee; +} + +div#cgit table.blame div.alt:nth-child(odd) { + background: white; +} + +div#cgit table.blame td.lines > div { + position: relative; +} + +div#cgit table.blame td.lines > div > pre { + padding: 0 0 0 0.5em; + position: absolute; + top: 0; +} + +div#cgit table.blame .oid { + font-size: 100%; +} + +div#cgit table.bin-blob { + margin-top: 0.5em; + border: solid 1px black; +} + +div#cgit table.bin-blob th { + font-family: monospace; + white-space: pre; + border: solid 1px #777; + padding: 0.5em 1em; +} + +div#cgit table.bin-blob td { + font-family: monospace; + white-space: pre; + border-left: solid 1px #777; + padding: 0em 1em; +} + +div#cgit table.nowrap td { + white-space: nowrap; +} + +div#cgit table.commit-info { + border-collapse: collapse; + margin-top: 1.5em; +} + +div#cgit div.cgit-panel { + float: right; + margin-top: 1.5em; +} + +div#cgit div.cgit-panel table { + border-collapse: collapse; + border: solid 1px #aaa; + background-color: #eee; +} + +div#cgit div.cgit-panel th { + text-align: center; +} + +div#cgit div.cgit-panel td { + padding: 0.25em 0.5em; +} + +div#cgit div.cgit-panel td.label { + padding-right: 0.5em; +} + +div#cgit div.cgit-panel td.ctrl { + padding-left: 0.5em; +} + +div#cgit table.commit-info th { + text-align: left; + font-weight: normal; + padding: 0.1em 1em 0.1em 0.1em; + vertical-align: top; +} + +div#cgit table.commit-info td { + font-weight: normal; + padding: 0.1em 1em 0.1em 0.1em; +} + +div#cgit div.commit-subject { + font-weight: bold; + font-size: 125%; + margin: 1.5em 0em 0.5em 0em; + padding: 0em; +} + +div#cgit div.commit-msg { + white-space: pre; + font-family: monospace; +} + +div#cgit div.notes-header { + font-weight: bold; + padding-top: 1.5em; +} + +div#cgit div.notes { + white-space: pre; + font-family: monospace; + border: solid 1px #ee9; + background-color: #ffd; + padding: 0.3em 2em 0.3em 1em; + float: left; +} + +div#cgit div.notes-footer { + clear: left; +} + +div#cgit div.diffstat-header { + font-weight: bold; + padding-top: 1.5em; +} + +div#cgit table.diffstat { + border-collapse: collapse; + border: solid 1px #aaa; + background-color: #eee; +} + +div#cgit table.diffstat th { + font-weight: normal; + text-align: left; + text-decoration: underline; + padding: 0.1em 1em 0.1em 0.1em; + font-size: 100%; +} + +div#cgit table.diffstat td { + padding: 0.2em 0.2em 0.1em 0.1em; + font-size: 100%; + border: none; +} + +div#cgit table.diffstat td.mode { + white-space: nowrap; +} + +div#cgit table.diffstat td span.modechange { + padding-left: 1em; + color: red; +} + +div#cgit table.diffstat td.add a { + color: green; +} + +div#cgit table.diffstat td.del a { + color: red; +} + +div#cgit table.diffstat td.upd a { + color: blue; +} + +div#cgit table.diffstat td.graph { + width: 500px; + vertical-align: middle; +} + +div#cgit table.diffstat td.graph table { + border: none; +} + +div#cgit table.diffstat td.graph td { + padding: 0px; + border: 0px; + height: 7pt; +} + +div#cgit table.diffstat td.graph td.add { + background-color: #5c5; +} + +div#cgit table.diffstat td.graph td.rem { + background-color: #c55; +} + +div#cgit div.diffstat-summary { + color: #888; + padding-top: 0.5em; +} + +div#cgit table.diff { + width: 100%; +} + +div#cgit table.diff td { + font-family: monospace; + white-space: pre; +} + +div#cgit table.diff td div.head { + font-weight: bold; + margin-top: 1em; + color: black; +} + +div#cgit table.diff td div.hunk { + color: #009; +} + +div#cgit table.diff td div.add { + color: green; +} + +div#cgit table.diff td div.del { + color: red; +} + +div#cgit .oid { + font-family: monospace; + font-size: 90%; +} + +div#cgit .left { + text-align: left; +} + +div#cgit .right { + text-align: right; +} + +div#cgit table.list td.reposection { + font-style: italic; + color: #888; +} + +div#cgit a.button { + font-size: 80%; + padding: 0em 0.5em; +} + +div#cgit a.primary { + font-size: 100%; +} + +div#cgit a.secondary { + font-size: 90%; +} + +div#cgit td.toplevel-repo { + +} + +div#cgit table.list td.sublevel-repo { + padding-left: 1.5em; +} + +div#cgit ul.pager { + list-style-type: none; + text-align: center; + margin: 1em 0em 0em 0em; + padding: 0; +} + +div#cgit ul.pager li { + display: inline-block; + margin: 0.25em 0.5em; +} + +div#cgit ul.pager a { + color: #777; +} + +div#cgit ul.pager .current { + font-weight: bold; +} + +div#cgit span.age-mins { + font-weight: bold; + color: #080; +} + +div#cgit span.age-hours { + color: #080; +} + +div#cgit span.age-days { + color: #040; +} + +div#cgit span.age-weeks { + color: #444; +} + +div#cgit span.age-months { + color: #888; +} + +div#cgit span.age-years { + color: #bbb; +} + +div#cgit span.insertions { + color: #080; +} + +div#cgit span.deletions { + color: #800; +} + +div#cgit div.footer { + margin-top: 0.5em; + text-align: center; + font-size: 80%; + color: #ccc; +} + +div#cgit div.footer a { + color: #ccc; + text-decoration: none; +} + +div#cgit div.footer a:hover { + text-decoration: underline; +} + +div#cgit a.branch-deco { + color: #000; + margin: 0px 0.5em; + padding: 0px 0.25em; + background-color: #88ff88; + border: solid 1px #007700; +} + +div#cgit a.tag-deco { + color: #000; + margin: 0px 0.5em; + padding: 0px 0.25em; + background-color: #ffff88; + border: solid 1px #777700; +} + +div#cgit a.tag-annotated-deco { + color: #000; + margin: 0px 0.5em; + padding: 0px 0.25em; + background-color: #ffcc88; + border: solid 1px #777700; +} + +div#cgit a.remote-deco { + color: #000; + margin: 0px 0.5em; + padding: 0px 0.25em; + background-color: #ccccff; + border: solid 1px #000077; +} + +div#cgit a.deco { + color: #000; + margin: 0px 0.5em; + padding: 0px 0.25em; + background-color: #ff8888; + border: solid 1px #770000; +} + +div#cgit div.commit-subject a.branch-deco, +div#cgit div.commit-subject a.tag-deco, +div#cgit div.commit-subject a.tag-annotated-deco, +div#cgit div.commit-subject a.remote-deco, +div#cgit div.commit-subject a.deco { + margin-left: 1em; + font-size: 75%; +} + +div#cgit table.stats { + border: solid 1px black; + border-collapse: collapse; +} + +div#cgit table.stats th { + text-align: left; + padding: 1px 0.5em; + background-color: #eee; + border: solid 1px black; +} + +div#cgit table.stats td { + text-align: right; + padding: 1px 0.5em; + border: solid 1px black; +} + +div#cgit table.stats td.total { + font-weight: bold; + text-align: left; +} + +div#cgit table.stats td.sum { + color: #c00; + font-weight: bold; +/* background-color: #eee; */ +} + +div#cgit table.stats td.left { + text-align: left; +} + +div#cgit table.vgraph { + border-collapse: separate; + border: solid 1px black; + height: 200px; +} + +div#cgit table.vgraph th { + background-color: #eee; + font-weight: bold; + border: solid 1px white; + padding: 1px 0.5em; +} + +div#cgit table.vgraph td { + vertical-align: bottom; + padding: 0px 10px; +} + +div#cgit table.vgraph div.bar { + background-color: #eee; +} + +div#cgit table.hgraph { + border: solid 1px black; + width: 800px; +} + +div#cgit table.hgraph th { + background-color: #eee; + font-weight: bold; + border: solid 1px black; + padding: 1px 0.5em; +} + +div#cgit table.hgraph td { + vertical-align: middle; + padding: 2px 2px; +} + +div#cgit table.hgraph div.bar { + background-color: #eee; + height: 1em; +} + +div#cgit table.ssdiff { + width: 100%; +} + +div#cgit table.ssdiff td { + font-size: 75%; + font-family: monospace; + white-space: pre; + padding: 1px 4px 1px 4px; + border-left: solid 1px #aaa; + border-right: solid 1px #aaa; +} + +div#cgit table.ssdiff td.add { + color: black; + background: #cfc; + min-width: 50%; +} + +div#cgit table.ssdiff td.add_dark { + color: black; + background: #aca; + min-width: 50%; +} + +div#cgit table.ssdiff span.add { + background: #cfc; + font-weight: bold; +} + +div#cgit table.ssdiff td.del { + color: black; + background: #fcc; + min-width: 50%; +} + +div#cgit table.ssdiff td.del_dark { + color: black; + background: #caa; + min-width: 50%; +} + +div#cgit table.ssdiff span.del { + background: #fcc; + font-weight: bold; +} + +div#cgit table.ssdiff td.changed { + color: black; + background: #ffc; + min-width: 50%; +} + +div#cgit table.ssdiff td.changed_dark { + color: black; + background: #cca; + min-width: 50%; +} + +div#cgit table.ssdiff td.lineno { + color: black; + background: #eee; + text-align: right; + width: 3em; + min-width: 3em; +} + +div#cgit table.ssdiff td.hunk { + color: black; + background: #ccf; + border-top: solid 1px #aaa; + border-bottom: solid 1px #aaa; +} + +div#cgit table.ssdiff td.head { + border-top: solid 1px #aaa; + border-bottom: solid 1px #aaa; +} + +div#cgit table.ssdiff td.head div.head { + font-weight: bold; + color: black; +} + +div#cgit table.ssdiff td.foot { + border-top: solid 1px #aaa; + border-left: none; + border-right: none; + border-bottom: none; +} + +div#cgit table.ssdiff td.space { + border: none; +} + +div#cgit table.ssdiff td.space div { + min-height: 3em; +} + +/* gruvbox.css - https://gitlab.com/imn1/gruvbox-cgit/-/blob/master/gruvbox_theme.css?ref_type=heads */ +:root { + --bg_h: #1d2021; + --bg: #282828; + --bg_s: #32302f; + --bg1: #3c3836; + --bg2: #504945; + --bg3: #665c54; + --bg4: #7c6f64; + + --fg: #fbf1c7; + --fg1: #ebdbb2; + --fg2: #d5c4a1; + --fg3: #bdae93; + --fg4: #a89984; + + --red: #fb4934; + --green: #b8bb26; + --yellow: #fabd2f; + --blue: #83a598; + --purple: #d3869b; + --aqua: #8ec07c; + --gray: #928374; + --orange: #fe8019; + + --red-dim: #cc2412; + --green-dim: #98971a; + --yellow-dim: #d79921; + --blue-dim: #458588; + --purple-dim: #b16286; + --aqua-dim: #689d6a; + --gray-dim: #a89984; + --orange-dim: #d65d0e; +} + +body, #cgit, .path, div#cgit table.blob td.hashes, +div#cgit table.blob td.lines, div#cgit div.cgit-panel table, +div#cgit table.diffstat { + background: var(--bg) !important; + color: var(--fg) !important; + border: none +} + +a { + color: var(--fg) !important; + text-decoration: underline !important; +} + +select, input { + border: none; + background: var(--bg2); + color: var(--fg); +} + +/**************/ +/*** TABLES ***/ +/**************/ +div#cgit table.tabs td a.active { + background: var(--bg) !important; + color: var(--yellow) !important; +} + +div#cgit table.tabs, div#cgit div.content, +div#cgit table#header td.sub { + border: none; +} + +div#cgit table.list tr.nohover, +div#cgit table.list tr:nth-child(2n) { + background: var(--bg) !important; +} + +div#cgit table.list tr:nth-child(2n+1) { + background: var(--bg_s) !important; +} + +div#cgit table.list tr:hover:not(.nohover) { + background: var(--bg1) !important; +} + +/************/ +/*** CODE ***/ +/************/ +div#cgit table.blob td.linenumbers, +div#cgit table.blob { + border-color: var(--gray); +} + +div#cgit table.blob td.linenumbers a { + color: var(--gray) !important; + text-decoration: none !important; +} + +.markdown-body code, .markdown-body tt, +.markdown-body .highlight pre, .markdown-body pre { + background: var(--bg1) !important; +} + +/************/ +/*** AGES ***/ +/************/ +.age-hours { + color: var(--aqua) !important; +} + +.age-days { + color: var(--aqua-dim) !important; +} + +.age-weeks { + color: var(--fg) !important; +} + +.age-months { + color: var(--fg2) !important; +} + +.age-years { + color: var(--fg4) !important; +} + +/******************/ +/*** DECORATORS ***/ +/******************/ +div#cgit a.branch-deco { + background: var(--aqua); + border: none; + color: var(--bg) !important; +} + +div#cgit a.deco { + background: var(--yellow); + border: none; + color: var(--bg) !important; +} + +div#cgit a.tag-deco { + background: var(--gray); + border: none; + color: var(--bg) !important; +} + +/************/ +/*** DIFF ***/ +/************/ +div#cgit table.diff td div.hunk { + color: var(--blue); +} + +div#cgit table.diff td div.del { + color: var(--red); +} + +div#cgit table.diff td div.add { + color: var(--green); +} + +div#cgit table.diff td div.ctx { + color: var(--gray); +} + +div#cgit table.diff td div.head { + color: var(--fg); +} + +div#cgit table.diffstat td.graph td.add { + background: var(--green); +} + +div#cgit table.diffstat td.graph td.rem { + background: var(--red); +} + diff --git a/static/cgit.png b/static/cgit.png new file mode 100644 index 0000000..bb7ffa1 Binary files /dev/null and b/static/cgit.png differ diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000..b94a688 Binary files /dev/null and b/static/favicon.ico differ -- cgit v1.2.3-70-g09d2