Skip to content

Latest commit

History

42 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Feel++ APT Repository Publisher

Repository URL: https://feelpp.github.io/apt/
Public key: feelpp.gpg

This repository contains the feelpp-aptly-publisher tool for publishing Debian packages to the Feel++ APT repository using aptly and GitHub Pages, with full support for multi-component publications.

Table of Contents

Repository Structure

The APT repository is organized as follows:

  • Channels (prefixes): stable/, testing/, pr/

    • stable: Production-ready packages
    • testing: Pre-release packages for testing
    • pr: Pull request builds for CI/CD
  • Distributions: noble, jammy, focal, bookworm, bullseye, etc.

    • Ubuntu codenames (noble = 24.04, jammy = 22.04, etc.)
    • Debian codenames (bookworm = 12, bullseye = 11, etc.)
  • Components (projects): Independent project namespaces

    • Examples: feelpp-project, mmg, parmmg, ktirio-urban-building, organ-on-chip
    • Each component can have multiple packages
    • Components are isolated - updates to one don't affect others

Client Setup

Add the Feel++ APT repository to your system:

# Download and install the GPG key
curl -fsSL https://feelpp.github.io/apt/feelpp.gpg \
| sudo tee /usr/share/keyrings/feelpp.gpg >/dev/null
# Add the repository (example: stable channel, noble distribution, multiple components)echo"deb [arch=amd64 signed-by=/usr/share/keyrings/feelpp.gpg] \https://feelpp.github.io/apt/stable noble mmg parmmg" \
| sudo tee /etc/apt/sources.list.d/feelpp-mmg.list
# Update package lists
sudo apt update
# Install packages
sudo apt install mmg libmmg5 libmmg-dev parmmg libparmmg5 libparmmg-dev

Note: Specify the components you need in the sources.list line. Available components can be found in the Release file.

Publishing Packages

Quick Start

  1. Install the publisher tool:
pip install feelpp-aptly-publisher
# or for development:
pip install -e .
  1. Build your Debian packages:
# Your package building process, e.g.:
dpkg-buildpackage -us -uc -b
  1. Publish to the repository:
feelpp-apt-publish \
--component my-project \
--channel stable \
--distro noble \
--debs /path/to/directory/with/debs

That's it! Your packages are now available at:

  • https://feelpp.github.io/apt/stable/dists/noble/my-project/

Publishing to Different Channels

Stable (production releases):

feelpp-apt-publish --component mmg --channel stable --distro noble --debs ./debs/

Testing (pre-release testing):

feelpp-apt-publish --component mmg --channel testing --distro noble --debs ./debs/

PR (continuous integration):

feelpp-apt-publish --component mmg --channel pr --distro noble --debs ./debs/

Multi-Component Support

The publisher automatically preserves existing components when adding or updating a component. You don't need to do anything special!

Example scenario:

  1. Initial state: Repository has component-a and component-b
  2. You publish component-c:
    feelpp-apt-publish --component component-c --channel stable --distro noble --debs ./debs/
  3. Result: Repository now has component-a, component-b, andcomponent-c

Updating an existing component:

# This will update component-a while preserving component-b and component-c
feelpp-apt-publish --component component-a --channel stable --distro noble --debs ./new-debs/

How it works:

  • The publisher reads the current Release file to detect existing components
  • It creates temporary repositories for existing components from the pool
  • It publishes all components together using aptly's multi-component support
  • Both Release and InRelease files are updated consistently

Command-Line Options

feelpp-apt-publish --help

Required options:

  • --component NAME: Component (project) name (will be normalized: My_Projectmy-project)
  • --distro NAME: Distribution codename (e.g., noble, jammy, bookworm)

Optional options:

  • --channel NAME: Publication channel (default: stable, options: stable, testing, pr)
  • --debs PATH: Directory containing .deb files (default: current directory)
  • --pages-repo URL: GitHub Pages repository (default: https://github.com/feelpp/apt.git)
  • --branch NAME: Git branch name (default: gh-pages)
  • --sign: Enable GPG signing (default: disabled)
  • --keyid ID: GPG key ID (required if --sign is used)
  • --verbose: Enable verbose logging

Examples:

# Minimal example (uses defaults: stable channel, skip signing)
feelpp-apt-publish --component mmg --distro noble --debs ./debs/
# Full example with all options
feelpp-apt-publish \
--component my-project \
--distro noble \
--channel testing \
--debs /tmp/my-debs \
--verbose
# With GPG signing
feelpp-apt-publish \
--component mmg \
--distro noble \
--sign \
--keyid ABCD1234 \
--debs ./debs/

Repository Cleanup

The publisher includes tools for cleaning up old packages, particularly pre-release versions (alpha, beta, rc) that accumulate over time.

Cleanup Commands

Analyze (Dry Run)

Analyze the repository to see what packages would be cleaned up:

# Analyze all channels
feelpp-apt-publish analyze --repo-path ./apt-repo
# Analyze specific channel
feelpp-apt-publish analyze --repo-path ./apt-repo --channels testing,pr
# Custom age limit (default: 90 days)
feelpp-apt-publish analyze --repo-path ./apt-repo --max-age-days 60
# Output as JSON for CI integration
feelpp-apt-publish analyze --repo-path ./apt-repo --json --output report.json

Cleanup (Execute)

Actually delete old packages:

# Preview what would be deleted (default: dry-run mode)
feelpp-apt-publish cleanup --repo-path ./apt-repo
# Execute cleanup
feelpp-apt-publish cleanup --repo-path ./apt-repo --execute
# Cleanup with custom age limit
feelpp-apt-publish cleanup --repo-path ./apt-repo --execute --max-age-days 60
# Cleanup specific channels only
feelpp-apt-publish cleanup --repo-path ./apt-repo --execute --channels pr

Retention Policies

Configure how packages are retained using a policy file:

# Create a default policy configuration
feelpp-apt-publish init-policy --output retention-policy.json
# Use custom policy
feelpp-apt-publish cleanup --repo-path ./apt-repo --policy retention-policy.json

Default policy file: retention-policy.json

{
"prerelease_max_age_days": 90,
"max_versions_per_package": 0,
"channel_policies": {
"stable": {
"keep_prereleases": true,
"max_versions": 0
},
"testing": {
"keep_prereleases": false,
"max_versions": 5
},
"pr": {
"keep_prereleases": false,
"max_versions": 3,
"max_age_days": 30
}
},
"protected_components": [],
"protected_packages": []
}

Policy Settings:

SettingDescriptionDefault
prerelease_max_age_daysMax age for pre-release packages90
max_versions_per_packageKeep N latest versions (0=unlimited)0
keep_prereleasesWhether to keep pre-releases in channelvaries
protected_componentsComponents to never clean[]
protected_packagesPackage name patterns to never clean[]

Automated Cleanup Workflows

The repository includes GitHub Actions workflows for automated cleanup:

1. Cleanup Analysis (Weekly Dry Run)

Workflow: .github/workflows/cleanup-dry-run.yml

Runs weekly (Sunday 3 AM UTC) to analyze what could be cleaned:

# Manual trigger with custom settingsgh workflow run "Cleanup Analysis (Dry Run)" \-f max-age-days=60 \-f channel=testing \-f include-stable-prereleases=false

2. Cleanup Old Packages (Monthly)

Workflow: .github/workflows/cleanup.yml

Runs monthly (1st of month, 4 AM UTC) to clean old pre-releases:

# Manual triggergh workflow run "Cleanup Old Packages" \-f max-age-days=90 \-f channel=all \-f dry-run=false# Preview mode (dry run)gh workflow run "Cleanup Old Packages" \-f dry-run=true

3. PR Channel Auto-Cleanup (Weekly)

Workflow: .github/workflows/cleanup-pr-channel.yml

Specifically cleans the PR channel (packages from closed PRs):

  • Runs weekly (Monday 5 AM UTC)
  • Removes packages older than 30 days
  • Can be triggered when a PR is closed via repository_dispatch
# Trigger cleanup for a specific closed PRcurl -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_TOKEN" \https://api.github.com/repos/feelpp/apt/dispatches \-d '{"event_type":"pr-closed","client_payload":{"pr_number":"123"}}'

What Gets Cleaned

Pre-release versions matching these patterns:

  • ~alpha, ~beta, ~rc1, ~pre, ~dev
  • ~git, ~svn, ~bzr
  • +git20231015, +svn1234
  • alpha1, beta2, rc3

Version limits (when configured):

  • Excess versions beyond max_versions setting
  • Oldest versions removed first (keeping newest)

Channel-specific defaults:

ChannelKeep Pre-releasesMax AgeMax Versions
stableYes-unlimited
testingNo90 days5
prNo30 days3

Installation

From PyPI (when published)

pip install feelpp-aptly-publisher

From Source

git clone https://github.com/feelpp/apt.git
cd apt
pip install -e .

Development Setup

# Install with development dependencies
pip install -e ".[dev]"# Or using the setup script
./setup-dev.sh

Development

Running Tests

# Run all tests
pytest
# Run only unit tests (fast)
pytest -m "not integration"# Run integration tests (slower, tests actual publishing)
pytest -m integration
# Run with coverage
pytest --cov=feelpp_aptly_publisher --cov-report=html

Code Quality

# Format code
black src/ tests/
# Lint
flake8 src/ tests/
# Type checking
mypy src/

Testing

The repository includes comprehensive tests:

  • Unit tests (tests/test_*.py): Fast tests for individual components

    • CLI argument parsing
    • Component name normalization
    • Publisher initialization
  • Integration tests (tests/test_integration.py): Full workflow tests

    • Single component publishing
    • Multi-component publishing (adding components)
    • Updating existing components
    • All three channels (stable, testing, pr)
    • Channel independence
    • Release/InRelease file consistency

Run the test suite:

# All tests
pytest -v
# Only integration tests
pytest -v -m integration
# Only unit tests (fast)
pytest -v -m "not integration"

Troubleshooting

Components Not Listed in InRelease

Problem: After publishing, packages install correctly but InRelease file doesn't list all components.

Solution: This was a bug in earlier versions. Update to feelpp-aptly-publisher >= 1.1.0 which fixes multi-component support.

Existing Components Lost After Publishing

Problem: Publishing a new component removes existing components from the repository.

Solution: Upgrade to version >= 1.1.0. The new version automatically detects and preserves all existing components.

Package Not Found After Publishing

Problem: Published package but apt update doesn't see it.

Checklist:

  1. Check that the component is listed in your sources.list
  2. Verify the component appears in the Release file:
    curl -s https://feelpp.github.io/apt/stable/dists/noble/Release | grep Components
  3. Check that packages exist:
    curl -s https://feelpp.github.io/apt/stable/dists/noble/COMPONENT/binary-amd64/Packages
  4. Wait a few minutes for GitHub Pages to update (caching)

Contributing

See CONTRIBUTING.md for development guidelines.

License

LGPL-3.0-or-later - see COPYING.LESSER

Authors

Feel++ Packaging Team contact@feelpp.org


Repository: https://github.com/feelpp/apt
Feel++ Project: https://www.feelpp.org

About

Apt repository

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages