Add workflow to update script timestamps on .sh changes
This workflow updates the timestamps of scripts in PocketBase whenever .sh files are changed in specified directories.
This commit is contained in:
committed by
GitHub
parent
5aa9cfe213
commit
195c064c71
167
.github/workflows/update-timestamp-on-db.yml
generated
vendored
Normal file
167
.github/workflows/update-timestamp-on-db.yml
generated
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
name: Update script timestamp on .sh changes
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "ct/**/*.sh"
|
||||
- "install/**/*.sh"
|
||||
- "tools/**/*.sh"
|
||||
- "turnkey/**/*.sh"
|
||||
- "vm/**/*.sh"
|
||||
|
||||
jobs:
|
||||
update-script-timestamp:
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get changed .sh files and derive slugs
|
||||
id: slugs
|
||||
run: |
|
||||
changed=$(git diff --name-only "${{ github.event.before }}" "${{ github.event.after }}" -- ct/ install/ tools/ turnkey/ vm/ | grep '\.sh$' || true)
|
||||
if [[ -z "$changed" ]]; then
|
||||
echo "No .sh files changed in ct/, install/, tools/, turnkey/, or vm/."
|
||||
echo "count=0" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
declare -A seen
|
||||
slugs=""
|
||||
for f in $changed; do
|
||||
[[ -f "$f" ]] || continue
|
||||
base="${f##*/}"
|
||||
base="${base%.sh}"
|
||||
if [[ "$f" == install/* && "$base" == *-install ]]; then
|
||||
slug="${base%-install}"
|
||||
else
|
||||
slug="$base"
|
||||
fi
|
||||
if [[ -z "${seen[$slug]:-}" ]]; then
|
||||
seen[$slug]=1
|
||||
slugs="$slugs $slug"
|
||||
fi
|
||||
done
|
||||
slugs=$(echo $slugs | xargs -n1 | sort -u)
|
||||
if [[ -z "$slugs" ]]; then
|
||||
echo "No slugs to update."
|
||||
echo "count=0" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
echo "$slugs" > changed_slugs.txt
|
||||
echo "count=$(echo "$slugs" | wc -w)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Parse PR number from merge commit
|
||||
id: pr
|
||||
run: |
|
||||
re='#([0-9]+)'
|
||||
if [[ "$COMMIT_MSG" =~ $re ]]; then
|
||||
echo "number=${BASH_REMATCH[1]}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "number=" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
env:
|
||||
COMMIT_MSG: ${{ github.event.head_commit.message }}
|
||||
|
||||
- name: Update script timestamps in PocketBase
|
||||
if: steps.slugs.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 }}
|
||||
COMMIT_URL: ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}
|
||||
PR_URL: ${{ steps.pr.outputs.number != '' && format('{0}/{1}/pull/{2}', github.server_url, github.repository, steps.pr.outputs.number) || '' }}
|
||||
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 apiBase = /\/api$/i.test(raw) ? raw : raw + '/api';
|
||||
const coll = process.env.POCKETBASE_COLLECTION;
|
||||
const slugsText = fs.readFileSync('changed_slugs.txt', 'utf8').trim();
|
||||
const slugs = slugsText ? slugsText.split(/\s+/).filter(Boolean) : [];
|
||||
if (slugs.length === 0) {
|
||||
console.log('No slugs to update.');
|
||||
return;
|
||||
}
|
||||
|
||||
const authUrl = apiBase + '/collections/users/auth-with-password';
|
||||
const authBody = JSON.stringify({
|
||||
identity: process.env.POCKETBASE_ADMIN_EMAIL,
|
||||
password: process.env.POCKETBASE_ADMIN_PASSWORD
|
||||
});
|
||||
const authRes = await request(authUrl, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: authBody
|
||||
});
|
||||
if (!authRes.ok) {
|
||||
throw new Error('Auth failed: ' + authRes.body);
|
||||
}
|
||||
const token = JSON.parse(authRes.body).token;
|
||||
const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records';
|
||||
|
||||
for (const slug of slugs) {
|
||||
const filter = "(slug='" + slug.replace(/'/g, "''") + "')";
|
||||
const listRes = await request(recordsUrl + '?filter=' + encodeURIComponent(filter) + '&perPage=1', {
|
||||
headers: { 'Authorization': token }
|
||||
});
|
||||
const list = JSON.parse(listRes.body);
|
||||
const record = list.items && list.items[0];
|
||||
if (!record) {
|
||||
console.log('Slug not in DB, skipping: ' + slug);
|
||||
continue;
|
||||
}
|
||||
const patchRes = await request(recordsUrl + '/' + record.id, {
|
||||
method: 'PATCH',
|
||||
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
name: record.name || record.slug,
|
||||
last_update_commit: process.env.PR_URL || process.env.COMMIT_URL || ''
|
||||
})
|
||||
});
|
||||
if (!patchRes.ok) {
|
||||
console.warn('PATCH failed for slug ' + slug + ': ' + patchRes.body);
|
||||
continue;
|
||||
}
|
||||
console.log('Updated timestamp for slug: ' + slug);
|
||||
}
|
||||
console.log('Done.');
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
ENDSCRIPT
|
||||
shell: bash
|
||||
Reference in New Issue
Block a user