Add workflow to push json changes to pocketbase

This commit is contained in:
Michel Roegl-Brunner
2026-03-02 14:36:02 +01:00
parent ee8ea672ef
commit cea9858193

View File

@@ -43,12 +43,41 @@ jobs:
POCKETBASE_ADMIN_PASSWORD: ${{ secrets.POCKETBASE_ADMIN_PASSWORD }} POCKETBASE_ADMIN_PASSWORD: ${{ secrets.POCKETBASE_ADMIN_PASSWORD }}
run: | run: |
node << 'ENDSCRIPT' node << 'ENDSCRIPT'
(async () => { (async function() {
const fs = require('fs'); const fs = require('fs');
const https = require('https');
const http = require('http');
const url = require('url');
function request(fullUrl, opts) {
return new Promise(function(resolve, reject) {
const u = url.parse(fullUrl);
const isHttps = u.protocol === 'https:';
const body = opts.body;
const options = {
hostname: u.hostname,
port: u.port || (isHttps ? 443 : 80),
path: u.path,
method: opts.method || 'GET',
headers: opts.headers || {}
};
if (body) options.headers['Content-Length'] = Buffer.byteLength(body);
const lib = isHttps ? https : http;
const req = lib.request(options, function(res) {
let data = '';
res.on('data', function(chunk) { data += chunk; });
res.on('end', function() {
resolve({ ok: res.statusCode >= 200 && res.statusCode < 300, statusCode: res.statusCode, body: data });
});
});
req.on('error', reject);
if (body) req.write(body);
req.end();
});
}
const base = process.env.POCKETBASE_URL.replace(/\/$/, '') + '/api'; const base = process.env.POCKETBASE_URL.replace(/\/$/, '') + '/api';
const coll = process.env.POCKETBASE_COLLECTION; const coll = process.env.POCKETBASE_COLLECTION;
const files = fs.readFileSync('changed_app_jsons.txt', 'utf8').trim().split(/\s+/).filter(Boolean); const files = fs.readFileSync('changed_app_jsons.txt', 'utf8').trim().split(/\s+/).filter(Boolean);
const authRes = await fetch(base + '/admins/auth-with-password', { const authRes = await request(base + '/admins/auth-with-password', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
@@ -56,36 +85,37 @@ jobs:
password: process.env.POCKETBASE_ADMIN_PASSWORD password: process.env.POCKETBASE_ADMIN_PASSWORD
}) })
}); });
if (!authRes.ok) throw new Error('Auth failed: ' + await authRes.text()); if (!authRes.ok) throw new Error('Auth failed: ' + authRes.body);
const { token } = await authRes.json(); const token = JSON.parse(authRes.body).token;
const recordsUrl = base + '/collections/' + encodeURIComponent(coll) + '/records'; const recordsPath = '/api/collections/' + encodeURIComponent(coll) + '/records';
const recordsUrl = base.replace(/\/api$/, '') + recordsPath;
for (const file of files) { for (const file of files) {
if (!fs.existsSync(file)) continue; if (!fs.existsSync(file)) continue;
const data = JSON.parse(fs.readFileSync(file, 'utf8')); const data = JSON.parse(fs.readFileSync(file, 'utf8'));
if (!data.slug) { console.log('Skipping', file, '(no slug)'); continue; } if (!data.slug) { console.log('Skipping', file, '(no slug)'); continue; }
const payload = { ...data, is_dev: false }; const payload = Object.assign({}, data, { is_dev: false });
const filter = "(slug='" + data.slug + "')"; const filter = "(slug='" + data.slug + "')";
const listRes = await fetch(recordsUrl + '?filter=' + encodeURIComponent(filter) + '&perPage=1', { const listRes = await request(recordsUrl + '?filter=' + encodeURIComponent(filter) + '&perPage=1', {
headers: { 'Authorization': token } headers: { 'Authorization': token }
}); });
const list = await listRes.json(); const list = JSON.parse(listRes.body);
const existingId = list.items && list.items[0] && list.items[0].id; const existingId = list.items && list.items[0] && list.items[0].id;
if (existingId) { if (existingId) {
console.log('Updating', file, '(slug=' + data.slug + ')'); console.log('Updating', file, '(slug=' + data.slug + ')');
const r = await fetch(recordsUrl + '/' + existingId, { const r = await request(recordsUrl + '/' + existingId, {
method: 'PATCH', method: 'PATCH',
headers: { 'Authorization': token, 'Content-Type': 'application/json' }, headers: { 'Authorization': token, 'Content-Type': 'application/json' },
body: JSON.stringify(payload) body: JSON.stringify(payload)
}); });
if (!r.ok) throw new Error('PATCH failed: ' + await r.text()); if (!r.ok) throw new Error('PATCH failed: ' + r.body);
} else { } else {
console.log('Creating', file, '(slug=' + data.slug + ')'); console.log('Creating', file, '(slug=' + data.slug + ')');
const r = await fetch(recordsUrl, { const r = await request(recordsUrl, {
method: 'POST', method: 'POST',
headers: { 'Authorization': token, 'Content-Type': 'application/json' }, headers: { 'Authorization': token, 'Content-Type': 'application/json' },
body: JSON.stringify(payload) body: JSON.stringify(payload)
}); });
if (!r.ok) throw new Error('POST failed: ' + await r.text()); if (!r.ok) throw new Error('POST failed: ' + r.body);
} }
} }
console.log('Done.'); console.log('Done.');