@stacksjs/defaults 0.74.33 → 0.74.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ai/skills/stacks-auto-imports/SKILL.md +1 -1
- package/ai/skills/stacks-dashboard/SKILL.md +60 -0
- package/ai/skills/stacks-orm/SKILL.md +1 -1
- package/ai/skills/stacks-storage/SKILL.md +58 -4
- package/app/Actions/Dashboard/Content/FileFavoriteAction.ts +25 -0
- package/app/Actions/Dashboard/Content/FileReprocessAction.ts +31 -0
- package/app/Actions/Dashboard/Content/FileTagsAction.ts +27 -0
- package/app/Actions/Dashboard/Content/file-manager.test.ts +47 -27
- package/app/Actions/Dashboard/Content/file-manager.ts +338 -12
- package/app/Actions/Dashboard/Content/file-metadata-store.ts +432 -0
- package/app/Actions/Dashboard/Content/file-metadata.test.ts +357 -0
- package/app/Actions/Dashboard/Content/file-metadata.ts +550 -0
- package/app/Actions/Dashboard/Content/file-pipeline.test.ts +344 -0
- package/app/Jobs/OptimizeStorageImageJob.ts +74 -0
- package/app/Jobs/TagStorageMediaJob.ts +122 -0
- package/app/Jobs/TranscodeStorageVideoJob.ts +88 -0
- package/app/Models/StorageItem.ts +123 -0
- package/app/Models/StorageItemTask.ts +134 -0
- package/ide/vscode/package.json +1 -1
- package/package.json +2 -2
- package/routes/dashboard-api.ts +10 -0
- package/vcs/github/workflows/buddy-bot.yml +109 -0
- package/vcs/github/workflows/ci.yml +3 -3
- package/vcs/github/workflows/release.yml +1 -1
- package/vcs/github/renovate.json +0 -5
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { defineModel } from '@stacksjs/orm'
|
|
2
|
+
import { schema } from '@stacksjs/validation'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Dashboard metadata for one file on one disk (stacksjs/stacks#2577).
|
|
6
|
+
*
|
|
7
|
+
* Every file-manager operation shipped before this maps to a `StorageAdapter`
|
|
8
|
+
* method - `write`, `list`, `moveFile`, `changeVisibility`, `deleteFile`. A disk
|
|
9
|
+
* knows a path, some bytes, a size and an ACL. It does not know that somebody
|
|
10
|
+
* starred a file, and there is nowhere on a disk to write that down: extended
|
|
11
|
+
* attributes do not survive a copy and cost a syscall per file, and S3 object
|
|
12
|
+
* metadata is set at write time, so starring a 2 GB video would rewrite 2 GB.
|
|
13
|
+
* Both are a database row wearing a disguise, so this is the row.
|
|
14
|
+
*
|
|
15
|
+
* ## The disk is authoritative, this table is advisory
|
|
16
|
+
*
|
|
17
|
+
* That is the question #2577 asks to settle first, and it decides everything
|
|
18
|
+
* else. A bucket several systems write to changes without the dashboard's
|
|
19
|
+
* knowledge, so a table that claimed to describe its contents would be wrong
|
|
20
|
+
* within a day of being right. Instead:
|
|
21
|
+
*
|
|
22
|
+
* - The listing comes from the disk and is joined to these rows. A path with no
|
|
23
|
+
* row is a file with no stars, which is the normal case and needs no row.
|
|
24
|
+
* - A row whose path no longer exists is an orphan and is simply not shown. The
|
|
25
|
+
* listing pass already enumerates every path in the subtree, so it sweeps the
|
|
26
|
+
* orphans it can prove are orphans - the ones under a prefix it just walked -
|
|
27
|
+
* at no extra cost. Nothing walks the whole disk to garbage collect.
|
|
28
|
+
* - Renames and deletes made THROUGH the dashboard reconcile eagerly, so a
|
|
29
|
+
* starred file keeps its star the moment it moves rather than waiting for a
|
|
30
|
+
* sweep. A folder rename is a prefix update, because moving a folder moves
|
|
31
|
+
* every file beneath it.
|
|
32
|
+
*
|
|
33
|
+
* The consequence worth stating: a file renamed outside the dashboard loses its
|
|
34
|
+
* metadata, because nothing connects the old path to the new one. That is not
|
|
35
|
+
* a gap to close later - a copy and a rename are indistinguishable to a bucket
|
|
36
|
+
* listing, so any reconciliation would be guessing.
|
|
37
|
+
*
|
|
38
|
+
* Keyed by `(disk, path)` rather than by a file id, because a disk has no file
|
|
39
|
+
* ids to key by.
|
|
40
|
+
*
|
|
41
|
+
* ## Tags are the existing vocabulary, reached the way the CMS reaches it
|
|
42
|
+
*
|
|
43
|
+
* #2577 asks for the existing vocabulary rather than a second one. That is the
|
|
44
|
+
* `tags` table, joined through the `taggable_models` pivot, with
|
|
45
|
+
* `taggable_type` keeping one model's attachments away from another's - which
|
|
46
|
+
* is what the dashboard's own tag manager writes and reads.
|
|
47
|
+
*
|
|
48
|
+
* `file-metadata-store.ts` queries it directly rather than declaring a
|
|
49
|
+
* `belongsToMany` here, because every operation is a set operation over a
|
|
50
|
+
* subtree and the relation would do them a row at a time. The relation would
|
|
51
|
+
* resolve correctly, though: `taggable_models.tag_id` is a `tags` id, which
|
|
52
|
+
* took stacksjs/stacks#2579 to establish - the migration comment and four
|
|
53
|
+
* queries in `@stacksjs/cms` said `taggables`, a different table belonging to a
|
|
54
|
+
* different mechanism.
|
|
55
|
+
*/
|
|
56
|
+
export default defineModel({
|
|
57
|
+
name: 'StorageItem',
|
|
58
|
+
table: 'storage_items',
|
|
59
|
+
primaryKey: 'id',
|
|
60
|
+
autoIncrement: true,
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* One row per file, enforced rather than assumed.
|
|
64
|
+
*
|
|
65
|
+
* Every write here is a get-or-create keyed on this pair, and a duplicate
|
|
66
|
+
* would not be a visible bug - it would be a file that is starred and also
|
|
67
|
+
* not starred, depending which row the query happened to read first.
|
|
68
|
+
*/
|
|
69
|
+
indexes: [
|
|
70
|
+
{
|
|
71
|
+
name: 'storage_items_disk_path_unique',
|
|
72
|
+
columns: ['disk', 'path'],
|
|
73
|
+
unique: true,
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
|
|
77
|
+
traits: {
|
|
78
|
+
useUuid: true,
|
|
79
|
+
useTimestamps: true,
|
|
80
|
+
|
|
81
|
+
useSearch: {
|
|
82
|
+
displayable: ['id', 'disk', 'path', 'favorite'],
|
|
83
|
+
searchable: ['path'],
|
|
84
|
+
sortable: ['path', 'createdAt'],
|
|
85
|
+
filterable: ['disk', 'favorite'],
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
useSeeder: { count: 0 },
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
attributes: {
|
|
92
|
+
disk: {
|
|
93
|
+
order: 1,
|
|
94
|
+
fillable: true,
|
|
95
|
+
// The disk NAME, not its driver: two disks can point at one bucket with
|
|
96
|
+
// different prefixes, and they are different namespaces to the dashboard.
|
|
97
|
+
validation: { rule: schema.string().required().min(1).max(64) },
|
|
98
|
+
factory: () => 'public',
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
path: {
|
|
102
|
+
order: 2,
|
|
103
|
+
fillable: true,
|
|
104
|
+
// Disk-relative and without a leading slash, exactly as the file manager
|
|
105
|
+
// reports it, so a lookup is an equality match rather than a normalization
|
|
106
|
+
// problem at every call site.
|
|
107
|
+
validation: { rule: schema.string().required().min(1).max(2048) },
|
|
108
|
+
factory: faker => `${faker.system.fileName()}`,
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
favorite: {
|
|
112
|
+
order: 3,
|
|
113
|
+
fillable: true,
|
|
114
|
+
default: false,
|
|
115
|
+
validation: { rule: schema.boolean() },
|
|
116
|
+
factory: () => false,
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
// Managed from the file manager, not as a top-level model row: a list of
|
|
121
|
+
// (disk, path, favorite) tuples is not a thing anybody wants to browse.
|
|
122
|
+
dashboard: { enabled: false },
|
|
123
|
+
} as const)
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { defineModel } from '@stacksjs/orm'
|
|
2
|
+
import { schema } from '@stacksjs/validation'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* One unit of background processing for one file (stacksjs/stacks#2578).
|
|
6
|
+
*
|
|
7
|
+
* The three things #245 asked for that could not happen inside a request -
|
|
8
|
+
* image optimization, video transcode, AI tagging - share the same shape:
|
|
9
|
+
* dispatch work and show what happened to it. Transcoding is minutes, not
|
|
10
|
+
* milliseconds; a vision call is a round trip to a third party. An upload
|
|
11
|
+
* handler that waits for either is an upload handler that times out.
|
|
12
|
+
*
|
|
13
|
+
* ## Why this is not a column on `StorageItem`
|
|
14
|
+
*
|
|
15
|
+
* A file can have three of these at once and they succeed and fail
|
|
16
|
+
* independently - a video whose transcode finished and whose tagging failed is
|
|
17
|
+
* a normal state, and a single `processing` column cannot say it. The file
|
|
18
|
+
* manager aggregates these rows into the one word a UI shows; the rows are what
|
|
19
|
+
* a retry and an error message need.
|
|
20
|
+
*
|
|
21
|
+
* It is also keyed by `(disk, path, kind)` rather than by a `storage_items` id,
|
|
22
|
+
* deliberately. A `storage_items` row exists only while somebody has starred or
|
|
23
|
+
* tagged the file - it is deleted when it has nothing left to say - and most
|
|
24
|
+
* uploads are neither. Hanging a task off it would mean creating a metadata row
|
|
25
|
+
* for every upload just to have somewhere to put the task.
|
|
26
|
+
*
|
|
27
|
+
* Same reconciliation rules as `storage_items`, through the same store: a
|
|
28
|
+
* rename moves these rows, a delete forgets them, and a completed listing
|
|
29
|
+
* sweeps the ones whose file is gone.
|
|
30
|
+
*/
|
|
31
|
+
export default defineModel({
|
|
32
|
+
name: 'StorageItemTask',
|
|
33
|
+
table: 'storage_item_tasks',
|
|
34
|
+
primaryKey: 'id',
|
|
35
|
+
autoIncrement: true,
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* One task per kind per file.
|
|
39
|
+
*
|
|
40
|
+
* Re-running replaces the row rather than adding a second, so "what happened
|
|
41
|
+
* to the transcode" has one answer. The history of previous attempts is the
|
|
42
|
+
* queue's to keep, not this table's.
|
|
43
|
+
*/
|
|
44
|
+
indexes: [
|
|
45
|
+
{
|
|
46
|
+
name: 'storage_item_tasks_disk_path_kind_unique',
|
|
47
|
+
columns: ['disk', 'path', 'kind'],
|
|
48
|
+
unique: true,
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
|
|
52
|
+
traits: {
|
|
53
|
+
useUuid: true,
|
|
54
|
+
useTimestamps: true,
|
|
55
|
+
|
|
56
|
+
useSearch: {
|
|
57
|
+
displayable: ['id', 'disk', 'path', 'kind', 'state'],
|
|
58
|
+
searchable: ['path'],
|
|
59
|
+
sortable: ['path', 'createdAt'],
|
|
60
|
+
filterable: ['disk', 'kind', 'state'],
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
useSeeder: { count: 0 },
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
attributes: {
|
|
67
|
+
disk: {
|
|
68
|
+
order: 1,
|
|
69
|
+
fillable: true,
|
|
70
|
+
validation: { rule: schema.string().required().min(1).max(64) },
|
|
71
|
+
factory: () => 'public',
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
path: {
|
|
75
|
+
order: 2,
|
|
76
|
+
fillable: true,
|
|
77
|
+
validation: { rule: schema.string().required().min(1).max(2048) },
|
|
78
|
+
factory: faker => faker.system.fileName(),
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
kind: {
|
|
82
|
+
order: 3,
|
|
83
|
+
fillable: true,
|
|
84
|
+
// `optimize` (images), `transcode` (video), `tag` (AI). An enum rather
|
|
85
|
+
// than free text so a typo in a dispatch is a validation error instead of
|
|
86
|
+
// a task nothing will ever run.
|
|
87
|
+
validation: { rule: schema.enum(['optimize', 'transcode', 'tag']) },
|
|
88
|
+
factory: () => 'optimize',
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
state: {
|
|
92
|
+
order: 4,
|
|
93
|
+
fillable: true,
|
|
94
|
+
default: 'queued',
|
|
95
|
+
validation: { rule: schema.enum(['queued', 'running', 'done', 'failed']) },
|
|
96
|
+
factory: () => 'queued',
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
attempts: {
|
|
100
|
+
order: 5,
|
|
101
|
+
fillable: true,
|
|
102
|
+
default: 0,
|
|
103
|
+
// Counted here as well as in the queue, because the queue's count is gone
|
|
104
|
+
// once the job leaves it and this is what the dashboard reads.
|
|
105
|
+
validation: { rule: schema.number() },
|
|
106
|
+
factory: () => 0,
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
error: {
|
|
110
|
+
order: 6,
|
|
111
|
+
fillable: true,
|
|
112
|
+
// The failure as the worker saw it. Truncated by the writer rather than
|
|
113
|
+
// by the column, so a stack trace does not silently lose its first line.
|
|
114
|
+
validation: { rule: schema.string().max(2000) },
|
|
115
|
+
factory: () => '',
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
startedAt: {
|
|
119
|
+
order: 7,
|
|
120
|
+
fillable: true,
|
|
121
|
+
validation: { rule: schema.string() },
|
|
122
|
+
factory: () => '',
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
finishedAt: {
|
|
126
|
+
order: 8,
|
|
127
|
+
fillable: true,
|
|
128
|
+
validation: { rule: schema.string() },
|
|
129
|
+
factory: () => '',
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
dashboard: { enabled: false },
|
|
134
|
+
} as const)
|
package/ide/vscode/package.json
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/defaults",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.74.
|
|
5
|
+
"version": "0.74.34",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/stacksjs/stacks.git",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@iconify-json/f7": "^1.2.2",
|
|
57
57
|
"@iconify-json/hugeicons": "^1.2.27",
|
|
58
|
-
"@stacksjs/mobile": "^0.74.
|
|
58
|
+
"@stacksjs/mobile": "^0.74.34",
|
|
59
59
|
"@stacksjs/sanitizer": "^0.2.113",
|
|
60
60
|
"ts-qr-codes": "^0.1.8"
|
|
61
61
|
}
|
package/routes/dashboard-api.ts
CHANGED
|
@@ -247,6 +247,16 @@ route.group({ prefix: '/api/dashboard', apiResponse: true }, () => {
|
|
|
247
247
|
guard(route.post('/files/uploads', 'Actions/Dashboard/Content/FileUploadAction'))
|
|
248
248
|
guard(route.patch('/files', 'Actions/Dashboard/Content/FileRenameAction'))
|
|
249
249
|
guard(route.put('/files/visibility', 'Actions/Dashboard/Content/FileVisibilityAction'))
|
|
250
|
+
// Favourites and tags are the metadata layer, not a storage operation: a disk
|
|
251
|
+
// has nowhere to record either, so both write `storage_items` and the listing
|
|
252
|
+
// above joins them back on (stacksjs/stacks#2577).
|
|
253
|
+
guard(route.put('/files/favorite', 'Actions/Dashboard/Content/FileFavoriteAction'))
|
|
254
|
+
guard(route.put('/files/tags', 'Actions/Dashboard/Content/FileTagsAction'))
|
|
255
|
+
// Re-running the background processing (stacksjs/stacks#2578). Not optional:
|
|
256
|
+
// the first version of any of these produces output somebody wants
|
|
257
|
+
// regenerated - a better ladder, a model that has improved, an optimization
|
|
258
|
+
// that ran before a preset changed.
|
|
259
|
+
guard(route.post('/files/reprocess', 'Actions/Dashboard/Content/FileReprocessAction'))
|
|
250
260
|
guard(route.post('/files/duplicates', 'Actions/Dashboard/Content/FileDuplicateAction'))
|
|
251
261
|
guard(route.delete('/files', 'Actions/Dashboard/Content/FileDestroyAction'))
|
|
252
262
|
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# The one dependency bot a generated app gets.
|
|
2
|
+
#
|
|
3
|
+
# The template used to ship a `renovate.json` instead, which opted every new app
|
|
4
|
+
# into a bot the framework's own policy does not use (AGENTS.md: "buddy-bot
|
|
5
|
+
# handles dependency updates, not renovatebot"). Running both is what
|
|
6
|
+
# stacksjs/stacks#2574 is about: the same bump arrives twice, two dashboards
|
|
7
|
+
# disagree, and a human picks a winner with nothing recording why.
|
|
8
|
+
#
|
|
9
|
+
# This is the app-shaped version of the framework's own buddy-bot workflow -
|
|
10
|
+
# the three scheduled jobs and the manual trigger, without the framework's
|
|
11
|
+
# release plumbing. Configure it in `config/buddy-bot.ts`.
|
|
12
|
+
name: Buddy Bot
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
schedule:
|
|
16
|
+
# Look for updates every two hours, then refresh the dashboard 15 minutes
|
|
17
|
+
# later so it reflects the pull requests that run just opened.
|
|
18
|
+
- cron: '0 */2 * * *'
|
|
19
|
+
- cron: '15 */2 * * *'
|
|
20
|
+
# Daily: close pull requests whose update already landed, and clean up the
|
|
21
|
+
# branches left behind.
|
|
22
|
+
- cron: '0 4 * * *'
|
|
23
|
+
|
|
24
|
+
workflow_dispatch:
|
|
25
|
+
inputs:
|
|
26
|
+
job:
|
|
27
|
+
description: Which job to run
|
|
28
|
+
required: false
|
|
29
|
+
default: all
|
|
30
|
+
type: choice
|
|
31
|
+
options:
|
|
32
|
+
- all
|
|
33
|
+
- check
|
|
34
|
+
- update
|
|
35
|
+
- dashboard
|
|
36
|
+
strategy:
|
|
37
|
+
description: Update strategy
|
|
38
|
+
required: false
|
|
39
|
+
default: patch
|
|
40
|
+
type: choice
|
|
41
|
+
options:
|
|
42
|
+
- all
|
|
43
|
+
- major
|
|
44
|
+
- minor
|
|
45
|
+
- patch
|
|
46
|
+
dry_run:
|
|
47
|
+
description: Dry run (preview only)
|
|
48
|
+
required: false
|
|
49
|
+
default: false
|
|
50
|
+
type: boolean
|
|
51
|
+
|
|
52
|
+
env:
|
|
53
|
+
# The built-in token is enough for commits, pull requests and issues.
|
|
54
|
+
# BUDDY_BOT_TOKEN (a PAT with `repo` and `workflow` scope) is only needed if
|
|
55
|
+
# you want buddy-bot to update workflow files themselves.
|
|
56
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
57
|
+
BUDDY_BOT_TOKEN: ${{ secrets.BUDDY_BOT_TOKEN }}
|
|
58
|
+
|
|
59
|
+
permissions:
|
|
60
|
+
contents: write
|
|
61
|
+
pull-requests: write
|
|
62
|
+
issues: write
|
|
63
|
+
|
|
64
|
+
# Serialize runs so a scheduled tick and a manual one cannot race on the same
|
|
65
|
+
# branches. `cancel-in-progress: false` lets the running job finish rather than
|
|
66
|
+
# being killed part-way through a commit.
|
|
67
|
+
concurrency:
|
|
68
|
+
group: buddy-bot-${{ github.ref }}
|
|
69
|
+
cancel-in-progress: false
|
|
70
|
+
|
|
71
|
+
jobs:
|
|
72
|
+
buddy-bot:
|
|
73
|
+
runs-on: ubuntu-latest
|
|
74
|
+
timeout-minutes: 30
|
|
75
|
+
|
|
76
|
+
steps:
|
|
77
|
+
- name: Checkout Code
|
|
78
|
+
uses: actions/checkout@v4
|
|
79
|
+
with:
|
|
80
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
81
|
+
# Rebasing an open branch needs the history it was cut from.
|
|
82
|
+
fetch-depth: 0
|
|
83
|
+
persist-credentials: true
|
|
84
|
+
|
|
85
|
+
- name: Setup Pantry
|
|
86
|
+
uses: pantry-pm/pantry/packages/action@fa35547da630b14beda5b26a2625490864d5c963 # v0.11.60
|
|
87
|
+
with:
|
|
88
|
+
version: '0.11.60'
|
|
89
|
+
install: 'false'
|
|
90
|
+
|
|
91
|
+
- name: Install Dependencies
|
|
92
|
+
run: bun install
|
|
93
|
+
|
|
94
|
+
- name: Configure Git
|
|
95
|
+
run: |
|
|
96
|
+
git config --global user.name "github-actions[bot]"
|
|
97
|
+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
98
|
+
|
|
99
|
+
- name: Open and refresh update pull requests
|
|
100
|
+
if: ${{ github.event.schedule == '0 */2 * * *' || (github.event_name == 'workflow_dispatch' && contains(fromJSON('["all", "update"]'), inputs.job)) }}
|
|
101
|
+
run: bunx buddy-bot update --strategy "${{ inputs.strategy || 'patch' }}" ${{ inputs.dry_run && '--dry-run' || '' }}
|
|
102
|
+
|
|
103
|
+
- name: Update the dependency dashboard
|
|
104
|
+
if: ${{ github.event.schedule == '15 */2 * * *' || (github.event_name == 'workflow_dispatch' && contains(fromJSON('["all", "dashboard"]'), inputs.job)) }}
|
|
105
|
+
run: bunx buddy-bot dashboard ${{ inputs.dry_run && '--dry-run' || '' }}
|
|
106
|
+
|
|
107
|
+
- name: Close landed pull requests and clean up branches
|
|
108
|
+
if: ${{ github.event.schedule == '0 4 * * *' || (github.event_name == 'workflow_dispatch' && contains(fromJSON('["all", "check"]'), inputs.job)) }}
|
|
109
|
+
run: bunx buddy-bot update-check ${{ inputs.dry_run && '--dry-run' || '' }}
|
|
@@ -30,7 +30,7 @@ jobs:
|
|
|
30
30
|
uses: actions/checkout@v4
|
|
31
31
|
|
|
32
32
|
- name: Setup Pantry
|
|
33
|
-
uses: pantry-pm/pantry/packages/action@
|
|
33
|
+
uses: pantry-pm/pantry/packages/action@fa35547da630b14beda5b26a2625490864d5c963 # v0.11.60
|
|
34
34
|
with:
|
|
35
35
|
install: 'false'
|
|
36
36
|
|
|
@@ -61,7 +61,7 @@ jobs:
|
|
|
61
61
|
uses: actions/checkout@v4
|
|
62
62
|
|
|
63
63
|
- name: Setup Pantry
|
|
64
|
-
uses: pantry-pm/pantry/packages/action@
|
|
64
|
+
uses: pantry-pm/pantry/packages/action@fa35547da630b14beda5b26a2625490864d5c963 # v0.11.60
|
|
65
65
|
with:
|
|
66
66
|
install: 'false'
|
|
67
67
|
|
|
@@ -95,7 +95,7 @@ jobs:
|
|
|
95
95
|
uses: actions/checkout@v4
|
|
96
96
|
|
|
97
97
|
- name: Setup Pantry
|
|
98
|
-
uses: pantry-pm/pantry/packages/action@
|
|
98
|
+
uses: pantry-pm/pantry/packages/action@fa35547da630b14beda5b26a2625490864d5c963 # v0.11.60
|
|
99
99
|
with:
|
|
100
100
|
install: 'false'
|
|
101
101
|
|
|
@@ -21,7 +21,7 @@ jobs:
|
|
|
21
21
|
fetch-depth: 0
|
|
22
22
|
|
|
23
23
|
- name: Setup Pantry
|
|
24
|
-
uses: pantry-pm/pantry/packages/action@
|
|
24
|
+
uses: pantry-pm/pantry/packages/action@fa35547da630b14beda5b26a2625490864d5c963 # v0.11.60
|
|
25
25
|
with:
|
|
26
26
|
install: 'false'
|
|
27
27
|
|