Compare commits

..

17 Commits

Author SHA1 Message Date
André Roth 8b544adf31 api: make updating name optional in repo edit
and path escape the new name param
2026-06-07 23:51:07 +02:00
André Roth 4cea5fadc7 tests: add api repo edit test 2026-06-07 23:51:07 +02:00
André Roth 8aceb2c3b0 tests: remove temporary folders 2026-06-07 23:51:07 +02:00
theoborealis 01b5aeb544 fixed urlencode for repo name in /put 2026-06-07 23:51:07 +02:00
André Roth 2974558aa7 cleanup 2026-06-07 23:46:43 +02:00
André Roth 00773f9840 ci: update codecov-action to 7.0.0 2026-06-07 22:53:09 +02:00
André Roth 8dc61cf362 ci: use correct ubuntu 26.04 codename 2026-05-17 10:16:01 +02:00
André Roth 4a9ddbdc34 Merge pull request #1565 from muresan/fix/aptly-crash-db-recover
Crash in aptly db recover
2026-05-15 16:51:51 +02:00
André Roth c316ea9b73 Merge pull request #1567 from aptly-dev/fix/doc-typos
docs: fix typos
2026-05-15 16:49:14 +02:00
André Roth d027a251ba Merge pull request #1571 from aptly-dev/feature/ubu26.04
ci: build for ubuntu 26.04
2026-05-15 16:48:55 +02:00
André Roth 16b6348710 ci: build for ubuntu 26.04 2026-05-15 00:05:35 +02:00
Catalin Muresan 1c1abe6b10 Added tests to please codeconv 2026-05-14 23:33:27 +02:00
Catalin Muresan c4bfbe52ca Fix crash in aptly db recover 2026-05-14 23:33:27 +02:00
André Roth c723fea807 docs: fix typos 2026-05-04 11:35:55 +02:00
André Roth 0d31298f37 Merge pull request #1568 from aptly-dev/fix/launchpad-test-dependency
Fix/launchpad test dependency
2026-05-04 11:30:56 +02:00
André Roth bba6bd7db5 system tests: do not depend on launchpad.net 2026-05-04 11:05:04 +02:00
André Roth faeaad0378 config: allow setting PPA Base URL 2026-05-04 11:05:04 +02:00
20 changed files with 107 additions and 17 deletions
+7 -4
View File
@@ -1,3 +1,4 @@
---
name: CI
on:
@@ -10,7 +11,6 @@ on:
defaults:
run:
# see: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#using-a-specific-shell
shell: bash --noprofile --norc -eo pipefail {0}
env:
@@ -33,7 +33,7 @@ jobs:
make docker-image
- name: "Unit Tests"
run: |
make docker-unit-tests
make docker-unit-test
mkdir -p out/coverage
mv unit.out out/coverage/
- uses: actions/upload-artifact@v4
@@ -140,7 +140,7 @@ jobs:
- name: "Upload Code Coverage"
if: github.actor != 'dependabot[bot]'
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@v7.0.0
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: coverage.txt
@@ -155,7 +155,7 @@ jobs:
strategy:
fail-fast: false
matrix:
name: ["Debian 13/trixie", "Debian 12/bookworm", "Debian 11/bullseye", "Ubuntu 24.04", "Ubuntu 22.04", "Ubuntu 20.04"]
name: ["Debian 13/trixie", "Debian 12/bookworm", "Debian 11/bullseye", "Ubuntu 26.04", "Ubuntu 24.04", "Ubuntu 22.04", "Ubuntu 20.04"]
arch: ["amd64", "i386" , "arm64" , "armhf"]
include:
- name: "Debian 13/trixie"
@@ -167,6 +167,9 @@ jobs:
- name: "Debian 11/bullseye"
suite: bullseye
image: debian:bullseye-slim
- name: "Ubuntu 26.04"
suite: resolute
image: ubuntu:26.04
- name: "Ubuntu 24.04"
suite: noble
image: ubuntu:24.04
+2 -2
View File
@@ -130,14 +130,14 @@ aptly version: 1.5.0+189+g0fc90dff
In order to run aptly unit tests, enter the following:
```
make docker-unit-tests
make docker-unit-test
```
#### Running system tests
In order to run aptly system tests, enter the following:
```
make docker-system-tests
make docker-system-test
```
#### Running golangci-lint
+2 -2
View File
@@ -194,7 +194,7 @@ docker-shell: ## Run aptly and other commands in docker container
docker-deb: ## Build debian packages in docker container
@$(DOCKER_RUN) -t aptly-dev /work/src/system/docker-wrapper dpkg DEBARCH=amd64
docker-unit-tests: ## Run unit tests in docker container (add TEST=regex to specify which tests to run)
docker-unit-test: ## Run unit tests in docker container (add TEST=regex to specify which tests to run)
$(DOCKER_RUN) -t --tmpfs /smallfs:rw,size=1m aptly-dev /work/src/system/docker-wrapper \
azurite-start \
AZURE_STORAGE_ENDPOINT=http://127.0.0.1:10000/devstoreaccount1 \
@@ -241,4 +241,4 @@ clean: ## remove local build and module cache
rm -f unit.out aptly.test VERSION docs/docs.go docs/swagger.json docs/swagger.yaml docs/swagger.conf
find system/ -type d -name __pycache__ -exec rm -rf {} \; 2>/dev/null || true
.PHONY: help man prepare swagger version binaries build docker-release docker-system-tests docker-unit-test docker-lint docker-build docker-image docker-man docker-shell docker-serve clean releasetype dpkg serve flake8
.PHONY: help man prepare swagger version binaries build docker-release docker-system-test docker-unit-test docker-lint docker-build docker-image docker-man docker-shell docker-serve clean releasetype dpkg serve flake8
+13 -3
View File
@@ -3,6 +3,7 @@ package api
import (
"fmt"
"net/http"
"net/url"
"os"
"path/filepath"
"sort"
@@ -175,7 +176,7 @@ func apiReposCreate(c *gin.Context) {
type reposEditParams struct {
// Name of repository to modify
Name *string `binding:"required" json:"Name" example:"repo1"`
Name *string ` json:"Name" example:"new-repo-name"`
// Change Comment of repository
Comment *string ` json:"Comment" example:"example repo"`
// Change Default Distribution for publishing
@@ -187,7 +188,7 @@ type reposEditParams struct {
// @Summary Update Repository
// @Description **Update local repository meta information**
// @Tags Repos
// @Param name path string true "Repository name"
// @Param name path string true "Repository name to modify"
// @Consume json
// @Param request body reposEditParams true "Parameters"
// @Produce json
@@ -200,11 +201,20 @@ func apiReposEdit(c *gin.Context) {
if c.Bind(&b) != nil {
return
}
if b.Name != nil {
new_name, err := url.PathUnescape(*b.Name)
if err != nil {
AbortWithJSONError(c, 400, err)
return
}
*b.Name = new_name
}
collectionFactory := context.NewCollectionFactory()
collection := collectionFactory.LocalRepoCollection()
name := c.Params.ByName("name")
name := c.Params.ByName("name") // repo to modify
repo, err := collection.ByName(name)
if err != nil {
AbortWithJSONError(c, 404, err)
+2 -1
View File
@@ -168,6 +168,8 @@ func (collection *LocalRepoCollection) Update(repo *LocalRepo) error {
// LoadComplete loads additional information for local repo
func (collection *LocalRepoCollection) LoadComplete(repo *LocalRepo) error {
repo.packageRefs = &PackageRefList{}
encoded, err := collection.db.Get(repo.RefKey())
if err == database.ErrNotFound {
return nil
@@ -176,7 +178,6 @@ func (collection *LocalRepoCollection) LoadComplete(repo *LocalRepo) error {
return err
}
repo.packageRefs = &PackageRefList{}
return repo.packageRefs.Decode(encoded)
}
+12
View File
@@ -133,6 +133,18 @@ func (s *LocalRepoCollectionSuite) TestByUUID(c *C) {
c.Assert(r.String(), Equals, repo.String())
}
func (s *LocalRepoCollectionSuite) TestLoadCompleteNoRefKey(c *C) {
repo := NewLocalRepo("local1", "Comment 1")
c.Assert(s.collection.Update(repo), IsNil)
r, err := s.collection.ByName("local1")
c.Assert(err, IsNil)
c.Assert(s.collection.LoadComplete(r), IsNil)
c.Assert(r.packageRefs, NotNil)
c.Assert(r.NumPackages(), Equals, 0)
}
func (s *LocalRepoCollectionSuite) TestUpdateLoadComplete(c *C) {
repo := NewLocalRepo("local1", "Comment 1")
c.Assert(s.collection.Update(repo), IsNil)
+6 -1
View File
@@ -28,6 +28,11 @@ func ParsePPA(ppaURL string, config *utils.ConfigStructure) (url string, distrib
}
}
baseurl := config.PpaBaseURL
if baseurl == "" {
baseurl = "http://ppa.launchpad.net"
}
codename := config.PpaCodename
if codename == "" {
codename, err = getCodename()
@@ -39,7 +44,7 @@ func ParsePPA(ppaURL string, config *utils.ConfigStructure) (url string, distrib
distribution = codename
components = []string{"main"}
url = fmt.Sprintf("http://ppa.launchpad.net/%s/%s/%s", matches[1], matches[2], distributorID)
url = fmt.Sprintf("%s/%s/%s/%s", baseurl, matches[1], matches[2], distributorID)
return
}
+3
View File
@@ -79,6 +79,9 @@ func (l *PackageRefList) Decode(input []byte) error {
// ForEach calls handler for each package ref in list
func (l *PackageRefList) ForEach(handler func([]byte) error) error {
if l == nil {
return nil
}
var err error
for _, p := range l.Refs {
err = handler(p)
+11
View File
@@ -130,6 +130,17 @@ func (s *PackageRefListSuite) TestPackageRefListForeach(c *C) {
c.Check(err, Equals, e)
}
func (s *PackageRefListSuite) TestForEachNilList(c *C) {
var l *PackageRefList
called := false
err := l.ForEach(func([]byte) error {
called = true
return nil
})
c.Assert(err, IsNil)
c.Assert(called, Equals, false)
}
func (s *PackageRefListSuite) TestHas(c *C) {
_ = s.list.Add(s.p1)
_ = s.list.Add(s.p3)
+3
View File
@@ -70,6 +70,9 @@ ppa_distributor_id: ubuntu
# Codename for short PPA url expansion
ppa_codename: ""
# PPA Base URL (default: launchpad)
# # ppa_baseurl: http://ppa.launchpad.net
# Aptly Server
###############
+1
View File
@@ -12,6 +12,7 @@
"dependencyVerboseResolve": false,
"ppaDistributorID": "ubuntu",
"ppaCodename": "",
"ppaBaseURL": "http://ppa.launchpad.net",
"serveInAPIMode": true,
"enableMetricsEndpoint": true,
"enableSwaggerEndpoint": false,
@@ -11,6 +11,7 @@ dep_follow_source: false
dep_verboseresolve: false
ppa_distributor_id: ubuntu
ppa_codename: ""
ppa_baseurl: http://ppa.launchpad.net
serve_in_api_mode: true
enable_metrics_endpoint: true
enable_swagger_endpoint: false
+3
View File
@@ -70,6 +70,9 @@ ppa_distributor_id: ubuntu
# Codename for short PPA url expansion
ppa_codename: ""
# PPA Base URL (default: launchpad)
# # ppa_baseurl: http://ppa.launchpad.net
# Aptly Server
###############
+2 -2
View File
@@ -1,4 +1,4 @@
Downloading: http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/dists/maverick/InRelease
Downloading: http://repo.aptly.info/system-tests/ppa/gladky-anton/gnuplot/ubuntu/dists/maverick/InRelease
gpgv: Signature made Sun Jul 28 07:57:01 2024 UTC
gpgv: using RSA key 5BFCD481D86D5824470E469F9000B1C3A01F726C
gpgv: Good signature from "Launchpad PPA for Anton Gladky"
@@ -6,5 +6,5 @@ gpgv: Signature made Sun Jul 28 07:57:01 2024 UTC
gpgv: using RSA key 02219381E9161C78A46CB2BFA5279A973B1F56C0
gpgv: Good signature from "Launchpad sim"
Mirror [mirror18]: http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/ maverick successfully added.
Mirror [mirror18]: http://repo.aptly.info/system-tests/ppa/gladky-anton/gnuplot/ubuntu/ maverick successfully added.
You can run 'aptly mirror update mirror18' to download repository contents.
@@ -1,5 +1,5 @@
Name: mirror18
Archive Root URL: http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/
Archive Root URL: http://repo.aptly.info/system-tests/ppa/gladky-anton/gnuplot/ubuntu/
Distribution: maverick
Components: main
Architectures: amd64, armel, i386, powerpc
+1
View File
@@ -221,6 +221,7 @@ class CreateMirror18Test(BaseTest):
"max-tries": 1,
"ppaDistributorID": "ubuntu",
"ppaCodename": "maverick",
"ppaBaseURL": "http://repo.aptly.info/system-tests/ppa",
}
fixtureCmds = [
+31
View File
@@ -461,3 +461,34 @@ class ReposAPITestCopyPackage(APITest):
self.check_equal(self.get(f"/api/repos/{repo2_name}/packages").json(),
['Pi386 libboost-program-options-dev 1.49.0.1 918d2f433384e378'])
class ReposAPITestCreateEdit(APITest):
"""
POST /api/repos,
"""
def check(self):
repo_name = self.random_name() + ' with space'
repo_desc = {'Comment': 'fun repo',
'DefaultComponent': 'contrib',
'DefaultDistribution': 'bookworm',
'Name': repo_name}
resp = self.post("/api/repos", json=repo_desc)
self.check_equal(resp.json(), repo_desc)
self.check_equal(resp.status_code, 201)
repo_desc = {'Comment': 'modified repo',
'DefaultComponent': 'main',
'DefaultDistribution': 'trixie',
'Name': repo_name + '@renamed'}
resp = self.put(f"/api/repos/{repo_name}", json=repo_desc)
self.check_equal(resp.json(), repo_desc)
self.check_equal(resp.status_code, 200)
resp = self.get("/api/repos/" + repo_name + '@renamed')
self.check_equal(resp.json(), repo_desc)
self.check_equal(resp.status_code, 200)
resp = self.delete("/api/repos/" + repo_name + '@renamed')
self.check_equal(resp.status_code, 200)
+1 -1
View File
@@ -3,7 +3,7 @@ import tempfile
class TestOut:
def __init__(self):
self.tmp_file = tempfile.NamedTemporaryFile(delete=False)
self.tmp_file = tempfile.NamedTemporaryFile(delete=True)
self.read_pos = 0
def fileno(self):
+2
View File
@@ -31,6 +31,7 @@ type ConfigStructure struct { // nolint: maligned
// PPA
PpaDistributorID string `json:"ppaDistributorID" yaml:"ppa_distributor_id"`
PpaCodename string `json:"ppaCodename" yaml:"ppa_codename"`
PpaBaseURL string `json:"ppaBaseURL" yaml:"ppa_baseurl"`
// Server
ServeInAPIMode bool `json:"serveInAPIMode" yaml:"serve_in_api_mode"`
@@ -235,6 +236,7 @@ var Config = ConfigStructure{
SkipLegacyPool: false,
PpaDistributorID: "ubuntu",
PpaCodename: "",
PpaBaseURL: "http://ppa.launchpad.net",
FileSystemPublishRoots: map[string]FileSystemPublishRoot{},
S3PublishRoots: map[string]S3PublishRoot{},
SwiftPublishRoots: map[string]SwiftPublishRoot{},
+3
View File
@@ -85,6 +85,7 @@ func (s *ConfigSuite) TestSaveConfig(c *C) {
" \"dependencyVerboseResolve\": false,\n" +
" \"ppaDistributorID\": \"\",\n" +
" \"ppaCodename\": \"\",\n" +
" \"ppaBaseURL\": \"\",\n" +
" \"serveInAPIMode\": false,\n" +
" \"enableMetricsEndpoint\": false,\n" +
" \"enableSwaggerEndpoint\": false,\n" +
@@ -252,6 +253,7 @@ func (s *ConfigSuite) TestSaveYAML2Config(c *C) {
"dep_verboseresolve: false\n" +
"ppa_distributor_id: \"\"\n" +
"ppa_codename: \"\"\n" +
"ppa_baseurl: \"\"\n" +
"serve_in_api_mode: false\n" +
"enable_metrics_endpoint: false\n" +
"enable_swagger_endpoint: false\n" +
@@ -308,6 +310,7 @@ dep_follow_source: true
dep_verboseresolve: true
ppa_distributor_id: Ubuntu
ppa_codename: code
ppa_baseurl: http://ppa.launchpad.net
serve_in_api_mode: true
enable_metrics_endpoint: true
enable_swagger_endpoint: true