- Dockerfile 100%
| .forgejo/workflows | ||
| actions | ||
| .dockerignore | ||
| Dockerfile | ||
| LICENSE | ||
| README.md | ||
Forgejo Actions
A collection of reusable composite actions for Forgejo CI/CD workflows, along with a base Docker image containing all necessary dependencies.
📦 Available Actions
Git & Repository Management
- checkout - Clone and checkout a Git repository at a specific commit/branch/tag
- create-tag - Create and push Git tags from version files
- list-changed-folders - Detect which folders changed since a git tag
Release Management
- create-release - Create releases and attach external package URLs
Python Development
- python-lint - Run Python linting tools (black, flake8, pylint, mypy, isort, ruff)
- python-build - Build Python packages using build, setuptools, or poetry
- python-test - Run Python tests with pytest or unittest with coverage support
- python-publish - Build and publish Python packages to Forgejo or PyPI-compatible registries
Rust Development
- rust-lint - Run Rust linting tools (clippy, rustfmt, cargo check, cargo audit)
- rust-build - Build Rust projects with cargo, including binary stripping and archiving
- rust-test - Run Rust tests with cargo test and optional code coverage using tarpaulin
- rust-publish - Publish Rust crates to crates.io or custom registries
Deno Development
- deno-lint - Run Deno linting tools (deno lint, deno fmt, deno check)
- deno-build - Build Deno projects with deno compile, creating standalone executables
- deno-test - Run Deno tests with deno test and optional code coverage reporting
- deno-publish - Publish Deno packages to JSR or npm registries
Package Publishing
Container Operations
- docker-login - Authenticate to a Docker registry
- docker-build - Build Docker images with tags and labels
- docker-push - Push Docker images to a registry
🐳 Base Docker Image
This repository includes a base Docker image (Dockerfile) that contains all dependencies needed to run these actions:
- Git (2.39+) with LFS support
- Python (3.11) with pip, twine, build, poetry
- Docker CLI with Buildx and Compose plugins
- Common utilities: bash, curl, wget, jq, tar, gzip, unzip, etc.
Using the Base Image
jobs:
my-job:
runs-on: ["self-hosted", "linux"]
container:
image: your-registry.com/actions-base:latest
options: --privileged # Only needed for Docker-in-Docker
steps:
- name: Checkout
uses: https://git.flety.net/damien/actions/actions/checkout@main
Building the Base Image
The base image is automatically built and pushed by the workflow in .forgejo/workflows/build-base-image.yml.
Manual build:
docker build -t your-registry.com/actions-base:latest .
docker push your-registry.com/actions-base:latest
🚀 Quick Start Examples
Example 1: Build and Push Docker Image
name: Build Docker Image
on:
push:
branches: [main]
tags: ["v*"]
jobs:
build:
runs-on: ["self-hosted", "linux"]
container:
image: docker:dind
options: --privileged
steps:
- name: Start Docker daemon
run: |
dockerd &
sleep 5
- name: Install dependencies
run: apk add --no-cache git bash curl
- name: Checkout code
uses: https://git.flety.net/damien/actions/actions/checkout@main
- name: Login to registry
uses: https://git.flety.net/damien/actions/actions/docker-login@main
with:
registry: ${{ github.server_url }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build image
uses: https://git.flety.net/damien/actions/actions/docker-build@main
with:
tags: ${{ github.server_url }}/${{ github.repository }}:latest
- name: Push image
uses: https://git.flety.net/damien/actions/actions/docker-push@main
with:
tags: ${{ github.server_url }}/${{ github.repository }}:latest
Example 2: Publish Python Package
name: Publish Package
on:
push:
tags: ["v*"]
jobs:
publish:
runs-on: ["self-hosted", "linux"]
container:
image: your-registry.com/actions-base:latest
steps:
- name: Checkout code
uses: https://git.flety.net/damien/actions/actions/checkout@main
- name: Publish to Forgejo
uses: https://git.flety.net/damien/actions/actions/python-publish@main
with:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
build: true
build-tool: build
Example 3: Create Release with Assets
name: Create Release
on:
push:
tags: ["v*"]
jobs:
release:
runs-on: ["self-hosted", "linux"]
container:
image: your-registry.com/actions-base:latest
steps:
- name: Checkout code
uses: https://git.flety.net/damien/actions/actions/checkout@main
- name: Build artifacts
run: |
make build
tar -czf my-app-linux-amd64.tar.gz dist/
- name: Create release
uses: https://git.flety.net/damien/actions/actions/create-release@main
with:
tag: ${{ github.ref_name }}
title: Release ${{ github.ref_name }}
body: |
Release notes for ${{ github.ref_name }}
files: ./my-app-linux-amd64.tar.gz
token: ${{ secrets.GITHUB_TOKEN }}
Example 4: Create Release with Package Links
name: Release with Packages
on:
push:
tags: ["v*"]
jobs:
publish:
runs-on: ["self-hosted", "linux"]
container:
image: your-registry.com/actions-base:latest
outputs:
package-url: ${{ steps.publish.outputs.package-url }}
steps:
- name: Checkout code
uses: https://git.flety.net/damien/actions/actions/checkout@main
- name: Publish to Forgejo
id: publish
uses: https://git.flety.net/damien/actions/actions/python-publish@main
with:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
build: true
release:
needs: [publish]
runs-on: ["self-hosted", "linux"]
container:
image: your-registry.com/actions-base:latest
steps:
- name: Checkout code
uses: https://git.flety.net/damien/actions/actions/checkout@main
- name: Create release with package links
uses: https://git.flety.net/damien/actions/actions/create-release@main
with:
tag: ${{ github.ref_name }}
title: Release ${{ github.ref_name }}
body: |
## Installation
```bash
pip install mypackage==${{ github.ref_name }}
```
package-urls: ${{ needs.publish.outputs.package-url }}
token: ${{ secrets.GITHUB_TOKEN }}
Example 5: Multi-Registry Docker Push
name: Push to Multiple Registries
on:
push:
tags: ["v*"]
jobs:
push:
runs-on: ["self-hosted", "linux"]
container:
image: docker:dind
options: --privileged
steps:
- name: Start Docker daemon
run: |
dockerd &
sleep 5
- name: Install dependencies
run: apk add --no-cache git bash curl
- name: Checkout
uses: https://git.flety.net/damien/actions/actions/checkout@main
- name: Login to Forgejo
uses: https://git.flety.net/damien/actions/actions/docker-login@main
with:
registry: git.flety.net
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker Hub
uses: https://git.flety.net/damien/actions/actions/docker-login@main
with:
registry: docker.io
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build image
uses: https://git.flety.net/damien/actions/actions/docker-build@main
with:
tags: |
git.flety.net/${{ github.repository }}:${{ github.ref_name }},
docker.io/myuser/myapp:${{ github.ref_name }}
- name: Push to all registries
uses: https://git.flety.net/damien/actions/actions/docker-push@main
with:
tags: |
git.flety.net/${{ github.repository }}:${{ github.ref_name }},
docker.io/myuser/myapp:${{ github.ref_name }}
Example 6: Complete Python CI/CD Pipeline
name: Python CI/CD
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
push:
tags: ["v*"]
jobs:
lint:
name: Lint
runs-on: ["self-hosted", "linux"]
container:
image: python:3.12
steps:
- name: Checkout code
uses: https://git.flety.net/damien/actions/actions/checkout@main
- name: Run linters
uses: https://git.flety.net/damien/actions/actions/python-lint@main
with:
source-dir: mypackage/
linters: black,flake8,isort
fail-fast: false
test:
name: Test
runs-on: ["self-hosted", "linux"]
container:
image: python:3.12
steps:
- name: Checkout code
uses: https://git.flety.net/damien/actions/actions/checkout@main
- name: Install package
run: pip install -e .[dev]
- name: Run tests with coverage
uses: https://git.flety.net/damien/actions/actions/python-test@main
with:
test-dir: tests/
coverage: true
coverage-fail-under: 80
source-dir: mypackage/
build:
name: Build
needs: [lint, test]
runs-on: ["self-hosted", "linux"]
container:
image: python:3.12
steps:
- name: Checkout code
uses: https://git.flety.net/damien/actions/actions/checkout@main
- name: Build package
uses: https://git.flety.net/damien/actions/actions/python-build@main
with:
build-tool: build
check-dist: true
publish:
name: Publish to Forgejo
if: startsWith(github.ref, 'refs/tags/')
needs: [build]
runs-on: ["self-hosted", "linux"]
container:
image: python:3.12
steps:
- name: Checkout code
uses: https://git.flety.net/damien/actions/actions/checkout@main
- name: Publish to Forgejo Packages
uses: https://git.flety.net/damien/actions/actions/python-publish@main
with:
username: ${{ github.actor }}
password: ${{ secrets.PACKAGE_TOKEN }}
verbose: true
release:
name: Create Release
if: startsWith(github.ref, 'refs/tags/')
needs: [publish]
runs-on: ["self-hosted", "linux"]
container:
image: python:3.12
steps:
- name: Checkout code
uses: https://git.flety.net/damien/actions/actions/checkout@main
- name: Extract version
id: version
run: |
VERSION="${GITHUB_REF#refs/tags/v}"
echo "version=${VERSION}" >> $GITHUB_OUTPUT
- name: Create release
uses: https://git.flety.net/damien/actions/actions/create-release@main
with:
tag: ${{ github.ref_name }}
title: Release ${{ github.ref_name }}
body: |
## Installation
```bash
pip install mypackage==${{ steps.version.outputs.version }}
```
token: ${{ secrets.GITHUB_TOKEN }}
📋 Requirements
All actions require:
- Bash shell
- Git (for repository-based actions)
- Appropriate network access to target services
See REQUIREMENTS.md for detailed requirements per action.
🔒 Security Best Practices
-
Use secrets for credentials: Never hardcode passwords or tokens
password: ${{ secrets.GITHUB_TOKEN }} # ✅ Good password: my-password-123 # ❌ Bad -
Limit token permissions: Use tokens with minimum required permissions
-
Pin action versions: Use specific commits or tags instead of
@mainin productionuses: https://git.flety.net/damien/actions/actions/checkout@v1.0.0 -
Review Docker image sources: Only use trusted base images
-
Use --privileged sparingly: Only when Docker-in-Docker is required
🛠️ Development
Adding New Actions
- Create a new directory under
actions/actions/ - Add an
action.ymlfile with inputs, outputs, and steps - Add a
README.mddocumenting usage - Update this README and
REQUIREMENTS.md - Test in a clean container environment
- Update base Docker image if new dependencies are needed
Testing Actions Locally
Using act or similar tools:
act -W .forgejo/workflows/your-workflow.yml
Building the Base Image Locally
docker build -t actions-base:dev .
docker run -it --rm actions-base:dev bash
📝 Action URL Format
When using these actions in workflows, use the full HTTPS URL:
uses: https://git.flety.net/damien/actions/actions/ACTION-NAME@REF
Where:
ACTION-NAMEis the action directory nameREFismain, a tag, or a commit SHA
🤝 Contributing
Contributions are welcome! Please:
- Follow existing patterns for action structure
- Document all inputs and outputs
- Add usage examples
- Test thoroughly in container environments
- Update all relevant documentation
📄 License
MIT License - See individual action files for details.
🔗 Related Resources
💡 Tips
- Caching: Consider using Docker layer caching for faster builds
- Parallelization: Run independent jobs in parallel when possible
- Resource limits: Set appropriate memory and CPU limits for containers
- Cleanup: Remove old Docker images and containers to save disk space
- Monitoring: Track workflow execution times and optimize bottlenecks
🐛 Troubleshooting
"failed to read action" error
- Ensure the action exists in the repository
- Check that the action has an
action.ymlfile - Verify the action has been pushed to the remote repository
Docker daemon not available
- Ensure
--privilegedflag is set in container options - Start the Docker daemon explicitly in your workflow
- Check Docker socket permissions
Permission denied errors
- Check file permissions in the workspace
- Verify token has required permissions
- Consider running as root for Docker operations
Python package installation failures
- Ensure
build-essentialandpython3-devare installed - Check for conflicting package versions
- Use virtual environments for isolation
For more help, open an issue or check individual action READMEs.