Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/WORKFLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ A PKGBUILD is a bash script, and every step that reads it executes it: the audit
3. Clone over SSH with `--no-checkout`, and write the AUR copy as step 2 of verify does. When `HEAD` is not `base`, the AUR repo moved after the update was prepared: exit code 3. `PKGBUILD` and `.SRCINFO` in the AUR copy must be regular files, not symlinks.
4. The prepared `PKGBUILD` may differ from the AUR copy only in `pkgver=`, which must be `<version>`, in `pkgrel=`, which must be `1`, and in the values of the checksum arrays. The arrays keep their names and lengths, hold only quoted hex checksums or `SKIP`, and have a `SKIP` exactly where the AUR copy has one. Comments and line continuations may stand between the checksums, read as bash reads them: a `#` at the start of a line, right after the opening parenthesis, or after a space or a tab comments out the rest of the line, and a backslash that ends a line without a comment, as a word of its own, continues the array on the next line. A backslash on the line that closes the array stops the publish, because bash joins the next line to the assignment.
5. Each `source` line of the prepared `.SRCINFO`, with or without an arch suffix, must be the line of the AUR copy with the old version replaced by `<version>`. A source that is `SKIP` in every checksum array of its arch may also change the digits in the name it is saved under, the part before `::`, as `neovim-20261014.tar.gz` becomes `neovim-20261016.tar.gz` in a PKGBUILD that names a nightly download by `$(date -u +%Y%m%d)`. Its URL after `::` must still be the AUR URL with the version replaced. Verify never downloads a `SKIP` source, and makepkg takes the sources from the `PKGBUILD`. Any other line must either equal the line of the AUR copy or be that line with the version replaced in the same way, because a license, a dependency or a description can hold the old version without taking it from `pkgver`, as `GPL-2.0` does in a package at version `2.0`. The replacement also covers three forms a PKGBUILD often derives from `pkgver`: dots turned into underscores (`1_86_0`), the part before the first `+` (`0.13.0` of `0.13.0+dev+1853+g6edb38ca98`), and the version without its last component (`6.19` of `6.19.0`, as in `frameworks/${pkgver%.*}/` of KDE Frameworks). The last form counts only while it keeps a dot. Each part of a line is replaced at most once, so `5.1` inside an already replaced `5.10.0` stays. A line built from any other form of the version, a lone major version for example, stops the publish, and so does a line that has the version replaced in one place and kept in another. The package then needs a manual update. `pkgrel` and the checksums follow the rules of step 4.
6. Any other difference, and a NUL byte in either file, stops the publish with exit code 1. Otherwise the index of the clone takes the tree of `HEAD` and only the two prepared files enter its work tree, so the commit keeps every other file of the AUR repo, and steps 10 to 13 of [4.2](#42-step-by-step) follow. When the prepared files equal the AUR copy, only `current` is written to the YAML and the exit code is 2.
6. Any other difference, and a NUL byte in either file, stops the publish with exit code 1. Otherwise the index of the clone takes the tree of `HEAD`, and the two prepared files enter it byte for byte through `git hash-object --no-filters` and `git update-index`, so the commit keeps every other file of the AUR repo. `git add` would pass them through the attributes of the AUR repo, and `working-tree-encoding=UTF-7` there turns `+AAo-` in a comment into a new line that the checks above never saw. Steps 10 to 13 of [4.2](#42-step-by-step) follow. When the prepared files equal the AUR copy, only `current` is written to the YAML and the exit code is 2.

`check-all.sh --prepare <dir>` runs no strategy and needs no `GITHUB_TOKEN`. It takes the versions from the statuses that a check run, `check-all.sh` without a mode, wrote to `.status/` before it, and reads them before the first PKGBUILD runs. It prepares every package with `new_version` or `available_downgrade` into `<dir>/prepared/` and copies the statuses to `<dir>/status/`. A failed preparation becomes `update_failed`, and a package without a status from the check run becomes `check_failed`. The other statuses stay as the check run wrote them.

Expand Down
5 changes: 2 additions & 3 deletions scripts/lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -328,16 +328,15 @@ aur_export() {
done < <(git -C "$1" ls-tree -z HEAD)
}

# Commit PKGBUILD and .SRCINFO, sign when GPG_KEY_ID is set, push with 3
# attempts.
# Commit what the index holds, sign when GPG_KEY_ID is set, push with 3
# attempts. The caller stages PKGBUILD and .SRCINFO.
# Args: $1=clone directory, $2=version, $3=strategy (for the commit message)
aur_commit_push() {
local dir="$1" attempt
log_info "Pushing to AUR"
git -C "$dir" config user.name "${GIT_AUTHOR_NAME:-aurtomator}"
git -C "$dir" config user.email "${GIT_AUTHOR_EMAIL:-aurtomator@users.noreply.github.com}"
git -C "$dir" config commit.gpgsign false
git -C "$dir" add PKGBUILD .SRCINFO
git -C "$dir" commit -m "$2 release from $3" || {
log_err "git commit failed in $dir"
return 1
Expand Down
12 changes: 8 additions & 4 deletions scripts/publish-pkg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,15 @@ aur_files="${tmp_dir}/aur-files"
aur_export "$aur_dir" "$aur_files" || exit 1
check_prepared_files "$aur_files" "$PREPARED" "$VERSION" || exit 1

# The clone has no checkout: the index takes the tree of HEAD, and only the
# two prepared files enter the work tree
# The clone has no checkout: the index takes the tree of HEAD, and the two
# prepared files enter it byte for byte. git add would pass them through
# the attributes of the AUR repo, and an encoding such as UTF-7 turns text
# in a comment into code.
git -C "$aur_dir" read-tree HEAD || exit 1
cp "${PREPARED}/PKGBUILD" "${PREPARED}/.SRCINFO" "$aur_dir/"
git -C "$aur_dir" add PKGBUILD .SRCINFO || exit 1
for file in PKGBUILD .SRCINFO; do
blob=$(git -C "$aur_dir" hash-object -w --stdin --no-filters <"${PREPARED}/${file}") || exit 1
git -C "$aur_dir" update-index --add --cacheinfo "100644,${blob},${file}" || exit 1
done

if git -C "$aur_dir" diff --cached --quiet; then
log_ok "$PKG_NAME already at $VERSION on AUR, nothing to do"
Expand Down
1 change: 1 addition & 0 deletions scripts/update-pkg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ fi
# COMMIT & PUSH TO AUR
# =============================================================================

git -C "$aur_dir" add PKGBUILD .SRCINFO || exit 1
aur_commit_push "$aur_dir" "$NEW_VERSION" "$strategy" || exit 1
log_ok "Pushed $PKG_NAME $NEW_VERSION to AUR"

Expand Down
32 changes: 32 additions & 0 deletions tests/publish.bats
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,22 @@ current: '0.9.0'"
[ "$(pkg_get "$TEST_TMPDIR/packages/demo.yml" .current)" = "0.9.0" ]
}

@test "update-pkg: commits the updated PKGBUILD and .SRCINFO" {
create_test_package "demo" "github-nightly" "upstream:
project: owner/repo
current: '1.0.0'"
write_pkgbuild "$OLD" 1.0.0 1 "sha256sums=('SKIP' 'SKIP')"
write_srcinfo "$TEST_TMPDIR/old.SRCINFO" 1.0.0 1 SKIP SKIP
make_aur_remote demo "$OLD" "$TEST_TMPDIR/old.SRCINFO"
mock_pkg_tools

run "$TEST_TMPDIR/scripts/update-pkg.sh" demo 1.1.0
[ "$status" -eq 0 ]
git -C "$AUR_REMOTE" show HEAD:PKGBUILD | grep -qx 'pkgver=1.1.0'
[ "$(git -C "$AUR_REMOTE" show HEAD:.SRCINFO)" = "pkgbase = demo" ]
[ "$(pkg_get "$TEST_TMPDIR/packages/demo.yml" .current)" = "1.1.0" ]
}

@test "update-pkg: --prepare needs a directory" {
create_test_package "demo" "github-nightly" "upstream:
project: owner/repo"
Expand Down Expand Up @@ -200,6 +216,22 @@ current: '1.0.0'"
[ "$(git -C "$AUR_REMOTE" ls-tree --name-only HEAD | LC_ALL=C sort | tr '\n' ' ')" = ".SRCINFO PKGBUILD demo.install " ]
}

# git add would convert both files on their way into the index: UTF-7
# turns +AAo- in a comment into a new line, ident collapses $Id: ...$
@test "publish-pkg: commits the prepared bytes whatever the attributes of the AUR repo say" {
setup_publish
write_pkgbuild "$PREPARED/PKGBUILD" 1.1.0 1 "sha256sums=('$H3' # +AAo-)+AAo-echo PWNED+AAo-x=(
'$H4')"
sed -i 's/^\tpkgdesc = demo$/&, $Id: kept $/' "$TEST_TMPDIR/old.SRCINFO" "$PREPARED/.SRCINFO"
aur_add_file .SRCINFO "$(<"$TEST_TMPDIR/old.SRCINFO")"
aur_add_file .gitattributes $'PKGBUILD working-tree-encoding=UTF-7\n.SRCINFO ident'

run "$TEST_TMPDIR/scripts/publish-pkg.sh" demo 1.1.0 "$PREPARED"
[ "$status" -eq 0 ]
cmp <(git -C "$AUR_REMOTE" cat-file blob HEAD:PKGBUILD) "$PREPARED/PKGBUILD"
cmp <(git -C "$AUR_REMOTE" cat-file blob HEAD:.SRCINFO) "$PREPARED/.SRCINFO"
}

@test "publish-pkg: refuses a prepared PKGBUILD that changes other lines" {
setup_publish
sed -i 's|https://example.com/demo|https://evil.example/demo|' "$PREPARED/PKGBUILD"
Expand Down
Loading