744dc806ffc2cf3998692a0e41a1d0a14415cf8e

Author
TheEdgeOfRage <git@theedgeofrage.com>
Committer
TheEdgeOfRage <git@theedgeofrage.com>
Date

Message

Embed migrations in main image

Diff

This diff is truncated to protect this page.

  1diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
  2index acc2ab1716cfe82f9b0173e363cc61fc89237133..1f07be58c7ba79f1602b3c44efa27c9ecd5b7cca 100644
  3--- a/.github/workflows/ci.yaml
  4+++ b/.github/workflows/ci.yaml
  5@@ -64,14 +64,5 @@ jobs:
  6           push: true
  7           tags: theedgeofrage/ytrssil:api
  8           target: api
  9-          cache-from: type=gha,scope=api
 10-          cache-to: type=gha,scope=api,mode=max
 11-
 12-      - name: Build and push migrations image
 13-        uses: docker/build-push-action@v7
 14-        with:
 15-          push: true
 16-          tags: theedgeofrage/ytrssil:migrations
 17-          target: migrations
 18-          cache-from: type=gha,scope=migrations
 19-          cache-to: type=gha,scope=migrations,mode=max
 20+          cache-from: type=gha
 21+          cache-to: type=gha,mode=max
 22diff --git a/AGENTS.md b/AGENTS.md
 23index b024fb202974a0ca0898165a20f284cedb780fc7..e52273a1420dfdae0df0c568258a676afaa206a3 100644
 24--- a/AGENTS.md
 25+++ b/AGENTS.md
 26@@ -13,7 +13,7 @@
 27 
 28 - **HTTP**: Gin router with dual interfaces (HTML pages + JSON API), authentication middleware, Datastar SSE-driven templates
 29 - **Handler**: Business logic layer orchestrating channels, videos, downloads, and cleanup routines
 30-- **Database**: PostgreSQL with pgx connection pooling, 7 migrations tracking schema evolution
 31+- **Database**: PostgreSQL with pgx connection pooling, embedded migrations run at startup via golang-migrate
 32 - **External**: YouTube API client, RSS feed parser, yt-dlp downloader wrapper
 33 
 34 **Key Features**: Subscribe to YouTube channels via RSS, track watched/unwatched videos with progress, async video downloads with status polling, automatic file cleanup (2 days after watched), YouTube Shorts detection
 35@@ -44,6 +44,6 @@ All Go tooling is managed via `make` targets. Never run `go` commands directly.
 36 - `make test` — runs `go test -timeout=30s -race ./...`
 37 - `make templ` — generates Go code from `.templ` files via `templ generate`. Required before build.
 38 - `make gen-mocks` — regenerates mock files in `mocks/` using moq. Run after changing interfaces in `db/`, `feedparser/`, or `lib/clients/youtube/`.
 39-- `make migrate` — applies PostgreSQL migrations from `migrations/` dir. Configurable via `DB_URI` env var (default: `postgres://ytrssil:ytrssil@localhost:5432/ytrssil?sslmode=disable`)
 40diff --git a/Dockerfile b/Dockerfile
 41index 676ba6f6a86234b7b1cb579d094c04acb8384cfc..6c8b808c4ede8e1cb750624bee09b3db55242d0a 100644
 42--- a/Dockerfile
 43+++ b/Dockerfile
 44@@ -26,6 +26,3 @@ COPY ./assets/ ./assets/
 45 RUN assets/load.sh && rm assets/load.sh;
 46 
 47 COPY --from=builder /app/dist/ ./
 48-
 49-FROM migrate/migrate:4 AS migrations
 50-COPY ./migrations/ /migrations/
 51diff --git a/Makefile b/Makefile
 52index fbe57c00e75b42244bfbbcef3a4bbbe730b606d4..195062957fa8cf7ffccadb1c9ae4f9c5d3aa9038 100644
 53--- a/Makefile
 54+++ b/Makefile
 55@@ -48,4 +48,3 @@ migrate: bin/migrate
 56 
 57 image-build:
 58 	docker buildx build --push -t theedgeofrage/ytrssil:api --target api .
 59-	docker buildx build --push -t theedgeofrage/ytrssil:migrations --target migrations .
 60diff --git a/cmd/main.go b/cmd/main.go
 61index ed201362e6d11d0408775531d83d9306025da6a3..3abe536474a367d3a50c57ba710047dd17302b62 100644
 62--- a/cmd/main.go
 63+++ b/cmd/main.go
 64@@ -52,6 +52,11 @@ func main() {
 65 		return
 66 	}
 67 
 68+	if err := db.RunMigrations(cfg.DBURI); err != nil {
 69+		logger.Error("Failed to run migrations", "error", err)
 70+		return
 71+	}
 72+
 73 	db, err := db.NewPostgresDB(logger, cfg.DBURI)
 74 	if err != nil {
 75 		logger.Error(
 76diff --git a/compose.yaml b/compose.yaml
 77index 12ef6cdf4a85f99d32fe4c51027ae780273dc307..2eaf10c2eb060ae5671631057f73d878f8c92349 100644
 78--- a/compose.yaml
 79+++ b/compose.yaml
 80@@ -31,17 +31,6 @@ services:
 81     volumes:
 82       - data:/var/lib/ytrssil
 83 
 84-  migrations:
 85-    image: theedgeofrage/ytrssil:migrations
 86-    restart: unless-stopped
 87-    depends_on:
 88-      - postgres
 89-    command:
 90-      - "-path=/migrations/"
 91-      - "-database"
 92-      - "postgresql://ytrssil:ytrssil@postgres/ytrssil?sslmode=disable"
 93-      - "up"
 94-
 95 volumes:
 96   postgres:
 97   data:
 98diff --git a/db/migrate.go b/db/migrate.go
 99new file mode 100644
100index 0000000000000000000000000000000000000000..32b18a8584e57cf0619948a4e38dc278aa331257
101--- /dev/null
102+++ b/db/migrate.go
103@@ -0,0 +1,26 @@
104+package db
105+
106+import (
107+	"github.com/golang-migrate/migrate/v4"
108+	_ "github.com/golang-migrate/migrate/v4/database/postgres"
109+	"github.com/golang-migrate/migrate/v4/source/iofs"
110+
111+	"github.com/TheEdgeOfRage/ytrssil-api/migrations"
112+)
113+
114+func RunMigrations(databaseURL string) error {
115+	source, err := iofs.New(migrations.FS, ".")
116+	if err != nil {
117+		return err
118+	}
119+
120+	m, err := migrate.NewWithSourceInstance("iofs", source, databaseURL)
121+	if err != nil {
122+		return err
123+	}
124+
125+	if err := m.Up(); err != nil && err != migrate.ErrNoChange {
126+		return err
127+	}
128+	return nil
129+}
130diff --git a/go.mod b/go.mod
131index 92e6b390416b0644de5ceda90c2fcc774f445448..0660eaa83f73497dcdf3a52670201e3bbba0d0fe 100644
132--- a/go.mod
133+++ b/go.mod
134@@ -6,6 +6,7 @@ require (
135 	github.com/a-h/templ v0.3.1001
136 	github.com/dustin/go-humanize v1.0.1
137 	github.com/gin-gonic/gin v1.11.0
138+	github.com/golang-migrate/migrate/v4 v4.19.1
139 	github.com/jackc/pgx/v5 v5.8.0
140 	github.com/jessevdk/go-flags v1.6.1
141 	github.com/oklog/ulid/v2 v2.1.1
142@@ -20,7 +21,7 @@ require (
143 	github.com/bytedance/sonic v1.14.0 // indirect
144 	github.com/bytedance/sonic/loader v0.3.0 // indirect
145 	github.com/cloudwego/base64x v0.1.6 // indirect
146-	github.com/davecgh/go-spew v1.1.1 // indirect
147+	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
148 	github.com/gabriel-vasile/mimetype v1.4.8 // indirect
149 	github.com/gin-contrib/sse v1.1.0 // indirect
150 	github.com/go-playground/locales v0.14.1 // indirect
151@@ -36,11 +37,12 @@ require (
152 	github.com/klauspost/cpuid/v2 v2.3.0 // indirect
153 	github.com/kr/text v0.2.0 // indirect
154 	github.com/leodido/go-urn v1.4.0 // indirect
155+	github.com/lib/pq v1.10.9 // indirect
156 	github.com/mattn/go-isatty v0.0.20 // indirect
157 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
158 	github.com/modern-go/reflect2 v1.0.2 // indirect
159 	github.com/pelletier/go-toml/v2 v2.2.4 // indirect
160-	github.com/pmezard/go-difflib v1.0.0 // indirect
161+	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
162 	github.com/quic-go/qpack v0.5.1 // indirect
163 	github.com/quic-go/quic-go v0.54.0 // indirect
164 	github.com/rogpeppe/go-internal v1.14.1 // indirect
165@@ -49,13 +51,13 @@ require (
166 	github.com/valyala/bytebufferpool v1.0.0 // indirect
167 	go.uber.org/mock v0.5.0 // indirect
168 	golang.org/x/arch v0.20.0 // indirect
169-	golang.org/x/crypto v0.41.0 // indirect
170-	golang.org/x/mod v0.27.0 // indirect
171-	golang.org/x/net v0.43.0 // indirect
172-	golang.org/x/sync v0.17.0 // indirect
173-	golang.org/x/sys v0.35.0 // indirect
174-	golang.org/x/text v0.29.0 // indirect
175-	golang.org/x/tools v0.36.0 // indirect
176+	golang.org/x/crypto v0.45.0 // indirect
177+	golang.org/x/mod v0.29.0 // indirect
178+	golang.org/x/net v0.47.0 // indirect
179+	golang.org/x/sync v0.18.0 // indirect
180+	golang.org/x/sys v0.38.0 // indirect
181+	golang.org/x/text v0.31.0 // indirect
182+	golang.org/x/tools v0.38.0 // indirect
183 	google.golang.org/protobuf v1.36.9 // indirect
184 	gopkg.in/yaml.v3 v3.0.1 // indirect
185 )
186diff --git a/go.sum b/go.sum
187index 59babae028cf07a2f65a296b57686a29b41559f9..717be2bd97c642838341e42dcf1486e6d261e2fd 100644
188--- a/go.sum
189+++ b/go.sum
190@@ -1,5 +1,9 @@
191+github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
192+github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
193 github.com/CAFxX/httpcompression v0.0.9 h1:0ue2X8dOLEpxTm8tt+OdHcgA+gbDge0OqFQWGKSqgrg=
194 github.com/CAFxX/httpcompression v0.0.9/go.mod h1:XX8oPZA+4IDcfZ0A71Hz0mZsv/YJOgYygkFhizVPilM=
195+github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
196+github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
197 github.com/a-h/templ v0.3.1001 h1:yHDTgexACdJttyiyamcTHXr2QkIeVF1MukLy44EAhMY=
198 github.com/a-h/templ v0.3.1001/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo=
199 github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
200@@ -11,18 +15,39 @@ github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZw
201 github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
202 github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
203 github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
204+github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
205+github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
206+github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
207+github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
208 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
209 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
210-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
211 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
212+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
213+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
214+github.com/dhui/dktest v0.4.6 h1:+DPKyScKSEp3VLtbMDHcUq6V5Lm5zfZZVb0Sk7Ahom4=
215+github.com/dhui/dktest v0.4.6/go.mod h1:JHTSYDtKkvFNFHJKqCzVzqXecyv+tKt8EzceOmQOgbU=
216+github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
217+github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
218+github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI=
219+github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
220+github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
221+github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
222+github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
223+github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
224 github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
225 github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
226+github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
227+github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
228 github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
229 github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
230 github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
231 github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
232 github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
233 github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
234+github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
235+github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
236+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
237+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
238 github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
239 github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
240 github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
241@@ -35,6 +60,10 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
242 github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
243 github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
244 github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
245+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
246+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
247+github.com/golang-migrate/migrate/v4 v4.19.1 h1:OCyb44lFuQfYXYLx1SCxPZQGU7mcaZ7gH9yH4jSFbBA=
248+github.com/golang-migrate/migrate/v4 v4.19.1/go.mod h1:CTcgfjxhaUtsLipnLoQRWCrjYXycRz/g5+RWDuYgPrE=
249 github.com/google/brotli/go/cbrotli v0.0.0-20230829110029-ed738e842d2f h1:jopqB+UTSdJGEJT8tEqYyE29zN91fi2827oLET8tl7k=
250 github.com/google/brotli/go/cbrotli v0.0.0-20230829110029-ed738e842d2f/go.mod h1:nOPhAkwVliJdNTkj3gXpljmWhjc4wCaVqbMJcPKWP4s=
251 github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
252@@ -64,15 +93,27 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
253 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
254 github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
255 github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
256+github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
257+github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
258 github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
259 github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
260+github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
261+github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
262+github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
263+github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
264 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
265 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
266 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
267 github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
268 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
269+github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
270+github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
271 github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s=
272 github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
273+github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
274+github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
275+github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
276+github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
277 github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c h1:P6XGcuPTigoHf4TSu+3D/7QOQ1MbL6alNwrGhcW7sKw=
278 github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c/go.mod h1:YnNlZP7l4MhyGQ4CBRwv6ohZTPrUJJZtEv4ZgADkbs4=
279 github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
280@@ -80,8 +121,11 @@ github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0
281 github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
282 github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ=
283 github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
284-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
285+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
286+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
287 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
288+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
289+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
290diff --git a/migrations/embed.go b/migrations/embed.go
291new file mode 100644
292index 0000000000000000000000000000000000000000..91cca1c33b8d3a236e0a2fb0f1e59a281ffec944
293--- /dev/null
294+++ b/migrations/embed.go
295@@ -0,0 +1,6 @@
296+package migrations
297+
298+import "embed"
299+
300+//go:embed *.sql
301+var FS embed.FS