- Melos 8.9 as the root's dev dependency, with scripts across the workspace (analyze, test:dart, test:flutter, generate, check) and its filters (--diff, --include-dependents); cli_util overridden to 0.5.2 for it, since Learn's flutter_launcher_icons asks for 0.4 and uses only its logger, unchanged in 0.5. - tool/check.dart in place of tool/check.sh: packages, formatting of our own files, analysis, the tools' tests, then every package's tests through Melos (--changed-since=<commit> for only what changed and what depends on it). tool/pre-push is the hook: the signature check, then the checks. CI generates every server's code and runs the same check. - The images build from the root with a workspace narrowed to what they need (tool/workspace_only.sh); compose, the deploy's migration test, the snap, the release script, the editor's launch files and Learn's asset tools (run from apps/learn) follow the new layout. - The project's source is named as project-halkyon/halkyon (source link, snap, F-Droid listing, release uploads); the AGPL packages carry the licence's own text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
46 lines
1.9 KiB
Shell
Executable file
46 lines
1.9 KiB
Shell
Executable file
#!/usr/bin/env bash
|
|
# Refuses a push to main that brings a commit not signed by a key in deploy/allowed-signers:
|
|
# the rule deploy/redeploy.sh applies before it deploys main, after CI passed. Checked here, a
|
|
# push of an unsigned commit fails on the laptop instead of after CI (it did on 2026-10-09,
|
|
# when 37 such commits had kept learn.halkyon.eu at v0.2.2 since 2026-10-07).
|
|
#
|
|
# tool/pre-push runs it first as the pre-push hook, passing on git's arguments (the remote) and
|
|
# stdin (a line per ref pushed: local ref, local commit, remote ref, remote commit). It checks
|
|
# the commits pushed to main that no ref of that remote has yet. By hand, for what main would
|
|
# bring:
|
|
#
|
|
# printf 'refs/heads/main %s refs/heads/main 0\n' "$(git rev-parse main)" |
|
|
# tool/check_signatures.sh origin
|
|
set -euo pipefail
|
|
|
|
remote=${1:-origin}
|
|
allowed=$(mktemp)
|
|
trap 'rm -f "$allowed"' EXIT
|
|
|
|
unsigned=''
|
|
while read -r _local_ref local_sha remote_ref _remote_sha; do
|
|
[ "$remote_ref" = refs/heads/main ] || continue
|
|
# Deleting a branch pushes no commits.
|
|
case $local_sha in *[!0]*) ;; *) continue ;; esac
|
|
# The list as the pushed commit has it; its comment lines match no fingerprint.
|
|
git show "$local_sha:deploy/allowed-signers" >"$allowed"
|
|
unsigned+=$(git log --format='%H %G? %GP' "$local_sha" --not --remotes="$remote" |
|
|
while read -r commit status key; do
|
|
# G: a good signature; U: good, by a key the keyring doesn't vouch for (the list does).
|
|
if { [ "$status" = G ] || [ "$status" = U ]; } && [ -n "$key" ] &&
|
|
grep -qx "$key" "$allowed"; then
|
|
continue
|
|
fi
|
|
echo "$commit"
|
|
done)$'\n'
|
|
done
|
|
|
|
if [ -n "${unsigned//[[:space:]]/}" ]; then
|
|
echo 'Not signed by a key in deploy/allowed-signers, which deploying main requires:' >&2
|
|
for commit in $unsigned; do
|
|
git log -1 --format=' %h %s' "$commit" >&2
|
|
done
|
|
echo 'Sign them, e.g. git rebase --force-rebase --gpg-sign <the commit before the first>,' \
|
|
'and push again.' >&2
|
|
exit 1
|
|
fi
|