Skip to main content

Generic Packages in CI/CD

Generic

/tmp/page308.md

Packages in CI/CD\n\nForgejo (and Gitea) provide a generic package registry that allows you to publish arbitrary files from CI/CD pipelines — ideal for distributing compiled binaries, configuration files, or any static assets.\n\n## Authentication\n\nForgejo requires Basic authentication for the generic packages API. This differs from the standard REST API which accepts Authorization: token headers.\n\nbash\ncurl --user \"<username>:<PAT>\" ...\n\n\nWhere <PAT> is a Personal Access Token with the write:package scope.\n\n## Publishing Files\n\n### Upload a single file\n\nbash\ncurl -X PUT \\\n --user \"<username>:<PAT>\" \\\n --upload-file ./mybinary \\\n https://git.example.com/api/packages/<owner>/generic/<repo>/<version>/<filename>\n\n\nPath components:\n\n| Component | Description |\n|-----------|-------------|\n| <owner> | Your username or organization name |\n| <repo> | Repository name (used as package namespace) |\n| <version> | Version string (e.g. v1.0.0, 0.2.1-rc1) |\n| <filename> | The actual file to upload |\n\n### Upload multiple files for the same version\n\nbash\ncurl -X PUT \\\n --user \"<username>:<PAT>\" \\\n --upload-file ./linux-binary \\\n https://git.example.com/api/packages/<owner>/generic/<repo>/<version>/linux-binary\n\ncurl -X PUT \\\n --user \"<username>:<PAT>\" \\\n --upload-file ./macos-binary \\\n https://git.example.com/api/packages/<owner>/generic/<repo>/<version>/macos-binary\n\n\nEach file is stored independently under the same version path.\n\n## Downloading Files\n\n### Direct download with authentication\n\nbash\ncurl -fsSL --user \"<username>:<PAT>\" \\\n https://git.example.com/api/packages/<owner>/generic/<repo>/<version>/<filename> \\\n --output ./downloaded-binary\n\n\nThe -fsSL flags:\n- -f: Fail silently on HTTP errors\n- -s: Silent mode (no progress meter)\n- -S: Show errors if silent mode is used\n- -L: Follow redirects\n\n### Without authentication (public packages)\n\nIf the package repository is public, you can download without credentials:\n\nbash\ncurl -fsSL \\\n https://git.example.com/api/packages/<owner>/generic/<repo>/<version>/<filename> \\\n --output ./downloaded-binary\n\n\n## GitHub Actions Workflow Example\n\nyaml\nname: Release\non:\n push:\n tags:\n - \"v*\"\n\npermissions:\n contents: write\n packages: write\n\njobs:\n release:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n\n - name: Build release binary\n run: cargo build --release\n\n - name: Upload to generic registry\n env:\n GITEA_TOKEN: ${{ secrets.PACKAGE_TOKEN }}\n run: |\n curl -X PUT \\\n --user \"$(echo \"${{ github.actor }}:$GITEA_TOKEN\" | base64)\" \\\n --upload-file target/release/myapp \\\n https://git.example.com/api/packages/${{ github.repository_owner }}/generic/myapp/${{ github.ref_name }}/myapp\n\n\n## Gitea Actions Workflow Example\n\nyaml\nname: Release\non:\n push:\n tags:\n - \"v*\"\n\njobs:\n release:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n\n - name: Build release binary\n run: cargo build --release\n\n - name: Upload to generic registry\n env:\n GITEA_TOKEN: ${{ secrets.PACKAGE_TOKEN }}\n run: |\n curl -X PUT \\\n --user \"username:$GITEA_TOKEN\" \\\n --upload-file target/release/myapp \\\n https://git.example.com/api/packages/${{ github.repository_owner }}/generic/myapp/${{ github.ref_name }}/myapp\n\n\n## Troubleshooting\n\n| Error | Cause | Solution |\n|-------|-------|----------|\n| 401 Unauthorized | Missing or invalid PAT | Verify token has write:package scope |\n| 403 Forbidden | Insufficient permissions | Ensure user has write access to the repository |\n| 404 Not Found | Wrong path or private package | Check owner/repo/version/filename; use auth for private packages |\n| 405 Method Not Allowed | Wrong HTTP method | Use PUT, not POST |\n| 500 Internal Server Error | Content-Type mismatch | Remove Content-Type: application/json; let curl auto-detect |\n\n## Key Differences: Forgejo vs Gitea\n\nBoth Forgejo and Gitea support generic packages, but authentication differs:\n\n| Endpoint | Gitea Auth | Forgejo Auth |\n|----------|-----------|---------------|\n| /api/v1/... (REST) | Authorization: token <PAT> | Authorization: token <PAT> |\n| /api/packages/... (packages) | Authorization: token <PAT> | Basic auth (--user user:token) |\n\nAlways use Basic auth for the packages API to ensure compatibility across both platforms.