mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-03-03 16:15:54 +00:00
126 lines
5.3 KiB
YAML
Generated
126 lines
5.3 KiB
YAML
Generated
name: Push JSON changes to PocketBase
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
paths:
|
|
- "frontend/public/json/**"
|
|
|
|
jobs:
|
|
push-json:
|
|
runs-on: self-hosted
|
|
steps:
|
|
- name: Checkout Repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Get changed JSON files with slug
|
|
id: changed
|
|
run: |
|
|
changed=$(git diff --name-only "${{ github.event.before }}" "${{ github.event.after }}" -- frontend/public/json/ | grep '\.json$' || true)
|
|
with_slug=""
|
|
for f in $changed; do
|
|
[[ -f "$f" ]] || continue
|
|
jq -e '.slug' "$f" >/dev/null 2>&1 && with_slug="$with_slug $f"
|
|
done
|
|
with_slug=$(echo $with_slug | xargs -n1)
|
|
if [[ -z "$with_slug" ]]; then
|
|
echo "No app JSON files changed (or no files with slug)."
|
|
echo "count=0" >> "$GITHUB_OUTPUT"
|
|
exit 0
|
|
fi
|
|
echo "$with_slug" > changed_app_jsons.txt
|
|
echo "count=$(echo "$with_slug" | wc -w)" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Push to PocketBase
|
|
if: steps.changed.outputs.count != '0'
|
|
env:
|
|
POCKETBASE_URL: ${{ secrets.POCKETBASE_URL }}
|
|
POCKETBASE_COLLECTION: ${{ secrets.POCKETBASE_COLLECTION }}
|
|
POCKETBASE_ADMIN_EMAIL: ${{ secrets.POCKETBASE_ADMIN_EMAIL }}
|
|
POCKETBASE_ADMIN_PASSWORD: ${{ secrets.POCKETBASE_ADMIN_PASSWORD }}
|
|
run: |
|
|
node << 'ENDSCRIPT'
|
|
(async function() {
|
|
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 raw = process.env.POCKETBASE_URL.replace(/\/$/, '');
|
|
const base = /\/api$/i.test(raw) ? raw : raw + '/api';
|
|
const coll = process.env.POCKETBASE_COLLECTION;
|
|
const files = fs.readFileSync('changed_app_jsons.txt', 'utf8').trim().split(/\s+/).filter(Boolean);
|
|
const authRes = await request(base + '/admins/auth-with-password', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
identity: process.env.POCKETBASE_ADMIN_EMAIL,
|
|
password: process.env.POCKETBASE_ADMIN_PASSWORD
|
|
})
|
|
});
|
|
if (!authRes.ok) throw new Error('Auth failed (check POCKETBASE_URL; use base URL without /api): ' + authRes.body);
|
|
const token = JSON.parse(authRes.body).token;
|
|
const recordsPath = '/api/collections/' + encodeURIComponent(coll) + '/records';
|
|
const recordsUrl = base.replace(/\/api$/, '') + recordsPath;
|
|
for (const file of files) {
|
|
if (!fs.existsSync(file)) continue;
|
|
const data = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
if (!data.slug) { console.log('Skipping', file, '(no slug)'); continue; }
|
|
const payload = Object.assign({}, data, { is_dev: false });
|
|
const filter = "(slug='" + data.slug + "')";
|
|
const listRes = await request(recordsUrl + '?filter=' + encodeURIComponent(filter) + '&perPage=1', {
|
|
headers: { 'Authorization': token }
|
|
});
|
|
const list = JSON.parse(listRes.body);
|
|
const existingId = list.items && list.items[0] && list.items[0].id;
|
|
if (existingId) {
|
|
console.log('Updating', file, '(slug=' + data.slug + ')');
|
|
const r = await request(recordsUrl + '/' + existingId, {
|
|
method: 'PATCH',
|
|
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(payload)
|
|
});
|
|
if (!r.ok) throw new Error('PATCH failed: ' + r.body);
|
|
} else {
|
|
console.log('Creating', file, '(slug=' + data.slug + ')');
|
|
const r = await request(recordsUrl, {
|
|
method: 'POST',
|
|
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(payload)
|
|
});
|
|
if (!r.ok) throw new Error('POST failed: ' + r.body);
|
|
}
|
|
}
|
|
console.log('Done.');
|
|
})().catch(e => { console.error(e); process.exit(1); });
|
|
ENDSCRIPT
|
|
shell: bash
|