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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ The setup script configures your identity (git author for AUR commits), SSH acce
| `github-asset` | GitHub Releases API | Assets re-uploaded on a fixed tag |
| `gitlab-tag` | GitLab Tags API | Any GitLab instance |
| `gitea-tag` | Gitea/Forgejo API | Codeberg, self-hosted Gitea |
| `git-latest` | `git clone --bare` | `-git` packages, any git repo |
| `git-latest` | `git clone --bare` | `-git` packages, any HTTPS git repo |
| `pypi` | PyPI JSON API | Python packages |
| `npm` | npm registry | Node.js packages |
| `crates` | crates.io API | Rust crates |
Expand Down
8 changes: 5 additions & 3 deletions docs/WORKFLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ upstream:

### 3.7 git-latest

**What it checks:** any git repository, through a bare clone.
**What it checks:** any git repository with an HTTPS URL, through a bare clone.

**When to use:** `-git` AUR packages that track the latest commit.

Expand All @@ -320,10 +320,12 @@ upstream:
| `upstream.type` | yes | One of: `github`, `gitlab`, `git` |
| `upstream.host` | depends | Required for the `gitlab` type |
| `upstream.project` | depends | Required for the `github` and `gitlab` types |
| `upstream.url` | depends | Required for the `git` type: full clone URL |
| `upstream.url` | depends | Required for the `git` type: full clone URL, `https://` only |

**How the version is extracted:** makes a bare clone into a temporary directory, counts the commits on `HEAD` (`git rev-list --count HEAD`), takes the short hash (`git rev-parse --short=7 HEAD`) and prints the usual `-git` format `r<count>.<shorthash>`, for example `r431.66db9ce`.

The clone runs with `GIT_ALLOW_PROTOCOL=http:https`. A URL in a package YAML that comes with a pull request therefore cannot read a local repository or connect to an ssh host with the SSH key of the machine that runs the check.

**Example YAML (GitHub):**

```yaml
Expand All @@ -345,7 +347,7 @@ upstream:
project: network/my-kde-app
```

**Example YAML (any git URL):**
**Example YAML (any HTTPS git URL):**

```yaml
name: my-package-git
Expand Down
2 changes: 1 addition & 1 deletion packages/example.yml.sample
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ upstream:
# type: github # required: github|gitlab|git
# project: owner/repo # required for github|gitlab
# host: gitlab.example.com # required for gitlab
# url: https://example.com/repo.git # required for type=git
# url: https://example.com/repo.git # required for type=git, https only

# --- pypi / npm / crates ----------------------------------------------------
# Language registries. PyPI and crates return stable releases only.
Expand Down
3 changes: 3 additions & 0 deletions scripts/validate-pkg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ validate_pkg() {
if [[ -z "$url" || "$url" == "null" ]]; then
log_err "$file: git-latest type 'git' requires 'upstream.url'"
((errors++))
elif [[ "$url" != https://* ]]; then
log_err "$file: upstream.url must use HTTPS: $url"
((errors++))
fi
;;
*)
Expand Down
5 changes: 3 additions & 2 deletions strategies/git-latest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,12 @@ case "$upstream_type" in
;;
esac

# Clone bare repo to get commit count + hash
# Clone bare repo to get commit count + hash. http and https only, so a URL
# from the YAML reaches no local repository and no ssh host.
tmp_dir=$(mktemp -d)
trap 'rm -rf "$tmp_dir"' EXIT

git clone --bare --quiet "$repo_url" "$tmp_dir/repo" || {
GIT_ALLOW_PROTOCOL=http:https git clone --bare --quiet "$repo_url" "$tmp_dir/repo" || {
echo "Failed to clone $repo_url" >&2
exit 1
}
Expand Down
45 changes: 44 additions & 1 deletion tests/strategies.bats
Original file line number Diff line number Diff line change
Expand Up @@ -273,12 +273,55 @@ teardown() {

create_test_package "test-git" "git-latest" "upstream:
type: git
url: ${fake_repo}"
url: https://git.example.com/repo.git"

# git that clones the fake repo in place of the URL, and logs the
# protocols the strategy allows
cat >"$MOCK_DIR/git" <<EOF
#!/usr/bin/env bash
if [[ "\$1" == "clone" ]]; then
echo "\${GIT_ALLOW_PROTOCOL:-unset} \${@: -2:1}" >>"$TEST_TMPDIR/git-clone"
exec env -u GIT_ALLOW_PROTOCOL /usr/bin/git clone "\${@:2:\$#-3}" "$fake_repo" "\${@: -1}"
fi
exec /usr/bin/git "\$@"
EOF
chmod +x "$MOCK_DIR/git"

run "$TEST_TMPDIR/strategies/git-latest.sh" "test-git"
[ "$status" -eq 0 ]
# Should match r3.<7-char-hash>
[[ "$output" =~ ^r3\.[0-9a-f]{7}$ ]]
[ "$(cat "$TEST_TMPDIR/git-clone")" = "http:https https://git.example.com/repo.git" ]
}

@test "git-latest: refuses a local repository" {
git init -q "$TEST_TMPDIR/local-repo"
git -C "$TEST_TMPDIR/local-repo" -c user.name=test -c user.email=test@test \
commit -q --allow-empty -m "commit 1"
create_test_package "test-git-file" "git-latest" "upstream:
type: git
url: file://$TEST_TMPDIR/local-repo"

run "$TEST_TMPDIR/strategies/git-latest.sh" "test-git-file"
[ "$status" -eq 1 ]
[[ "$output" == *"transport 'file' not allowed"* ]]
}

@test "git-latest: refuses an ssh URL without connecting" {
cat >"$MOCK_DIR/ssh" <<EOF
#!/usr/bin/env bash
echo "\$*" >>"$TEST_TMPDIR/ssh.args"
exit 255
EOF
chmod +x "$MOCK_DIR/ssh"
create_test_package "test-git-ssh" "git-latest" "upstream:
type: git
url: ssh://git.example.com/repo.git"

run "$TEST_TMPDIR/strategies/git-latest.sh" "test-git-ssh"
[ "$status" -eq 1 ]
[[ "$output" == *"transport 'ssh' not allowed"* ]]
[ ! -e "$TEST_TMPDIR/ssh.args" ]
}

# === github-nightly ===
Expand Down
18 changes: 18 additions & 0 deletions tests/validate-pkg.bats
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,24 @@ teardown() {
[ "$status" -eq 0 ]
}

@test "validate: git-latest git type fails on a URL without HTTPS" {
create_test_package "mypkg" "git-latest" "upstream:
type: git
url: file:///srv/repo"
run "$TEST_TMPDIR/scripts/validate-pkg.sh" "mypkg"
[ "$status" -eq 1 ]
[[ "$output" == *"upstream.url must use HTTPS: file:///srv/repo"* ]]
}

@test "validate: git-latest git type fails on an HTTP URL" {
create_test_package "mypkg" "git-latest" "upstream:
type: git
url: http://git.example.com/repo.git"
run "$TEST_TMPDIR/scripts/validate-pkg.sh" "mypkg"
[ "$status" -eq 1 ]
[[ "$output" == *"upstream.url must use HTTPS: http://git.example.com/repo.git"* ]]
}

@test "validate: pypi passes" {
create_test_package "mypkg" "pypi" "upstream:
registry: requests"
Expand Down
Loading