Make it easier to reason about state transitions
[tails.git] / bin / merge-main-branch
blob8a809f0b3f0dd7eb8641671cbf8d7ff7d0c9fdb2
1 #!/bin/bash
3 # shellcheck disable=SC2029
5 set -eu
7 error () {
8 echo "error: ${*}" >&2
9 exit 1
12 USAGE="Usage: $(basename "$0") SRC DST"
14 [ $# -eq 2 ] || error "$USAGE"
16 SRC="$1"
17 DST="$2"
18 WORKDIR=$(mktemp -d)
20 packages_in_suite() {
21 local suite="$1"
22 [ -n "$suite" ] || return 1
23 ssh reprepro@incoming.deb.tails.boum.org reprepro list "$suite" \
24 | sed -r 's,^([^|]+\|){2},,' \
25 | sort --stable --key=1,1 --key=2,2
28 ### Save the list of packages currently present in the APT suite we
29 ### want to merge into
31 packages_in_suite "$DST" > "$WORKDIR/$DST.orig.list"
33 ### Make sure we are not going to overwrite newer packages with older
34 ### ones
36 echo "I: Diff between the $SRC and $DST custom APT suites:"
38 ssh reprepro@incoming.deb.tails.boum.org \
39 tails-diff-suites "$SRC" "$DST"
41 echo "Check, in the above diff, if any package is newer in $DST than in $SRC."
42 echo "Abort if, and only if, that's the case."
43 echo -n "Proceed with the merge? (y/n) "
44 read -r answer
45 [ "$answer" = 'y' ] || exit 1
47 echo "I: merging the $SRC Git branch into $DST"
48 echo "I: If you have to resolve a merge conflict in debian/changelog,"
49 echo "I: ensure only the latest UNRELEASED entry is present,"
50 echo "and remove older versions that were never released."
51 git checkout "$DST"
52 git merge "origin/$DST"
53 git merge "$SRC"
55 echo "I: merging the $SRC APT suite into $DST"
56 ssh reprepro@incoming.deb.tails.boum.org \
57 tails-merge-suite "$SRC" "$DST"
59 echo "I: Restoring config/base_branch on $DST if needed"
60 echo "${DST}" > config/base_branch
61 git commit config/base_branch -m "Restore ${DST}'s base branch." || :
63 echo "I: Pushing the $DST Git branch"
64 git push origin "${DST}:${DST}"
66 packages_in_suite "$DST" > "$WORKDIR/$DST.new.list"
68 echo "I: Diff between the $DST APT suite before and after merging:"
69 set +e
70 diff -Naur "$WORKDIR/$DST.orig.list" "$WORKDIR/$DST.new.list"
71 RET=$?
72 set -e
73 case "$RET" in
74 0|1)
75 # diff did its job just fine
79 # diff had trouble
80 error "diff(1) failed."
83 # undocumented diff exit code
84 error "diff(1) returned $? -- I don't know what it means."
86 esac
87 echo "Verify that the merge did not re-add to $DST any package that was"
88 echo "removed from it on purpose earlier."
89 echo "If there are any, remove them manually."