Search by

omnibase / forge

GlitchArt

Software forge for base-bundle: releases built from git tags, free and licensed downloads, a private Composer repository, client projects with a shared board, prepaid support hours and quotes - paid through base-bundle-market

Package info

github.com/glitchr-studio/omnibase-forge

Type:symfony-bundle

pkg:composer/omnibase/forge

Statistics

Installs: 4

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-10-01 14:30 UTC

This package is auto-updated.

Last update: 2026-10-01 14:31:07 UTC


README

A software forge for base-bundle applications, sold through base-bundle-market. It covers what a studio sells besides its time on a site:

  • Software and releases. Each git tag of a repository becomes a release. git/git-bundle reads the tree in-process and the release is zipped from it.
  • Downloads. Free software downloads for anyone. Licensed software downloads against a licence bought as a market product (LicenseOffer). Files are served through signed, short-lived URLs and nginx X-Accel-Redirect.
  • A private Composer repository. /composer/packages.json lists the free packages for anyone, and the licensed ones for the holder of a valid licence. Authentication is HTTP Basic with the e-mail and the licence key.
  • Client projects.
    • A board the client and the studio both move cards on.
    • The time the studio logs, and the history of the project's repository.
  • Support hours.
    • Prepaid packs (HourPack) credit a ledger.
    • Logged time debits it.
    • The balance is always the sum of the ledger's lines.
  • Quotes (special offers).
    1. A client asks for a quote from the site.
    2. The studio prices it in the back office and sends it.
    3. The client accepts it and pays it like any order.
    4. Its hours are credited.

Requirements

  • PHP 8.2+, ext-zip
  • glitchr/omnibase 3.x, omnibase/admin, omnibase/marketplace
  • git/git-bundle 1.0, with the php-git2 extension (RogerGee/php-git2)
  • glitchr/omnistate with omnistate/annuaire-entreprises: they turn on base-bundle-market's company register, which checks the SIRETs typed in quote requests against the State's free register

Installation

composer require omnibase/forge:dev-main
// config/bundles.php
Omnistate\Bridge\Symfony\OmnistateBundle::class => ['all' => true],
Base\Forge\ForgeBundle::class => ['all' => true],
# config/routes.yaml
forge_controller:
    resource: "@ForgeBundle/src/Controller"
    type: attribute
    prefix: /
# config/packages/forge.yaml: every key is optional
forge:
    storage_dir: '%kernel.project_dir%/var/storage/forge'          # release archives, never under public/
    repositories_dir: '%kernel.project_dir%/var/storage/repositories'
    accel_prefix: '/_protected/forge/'   # nginx internal location; empty: PHP streams the file
    download_ttl: 600                    # seconds a signed link stays valid
    support_store: support               # market store selling hour packs and quotes
    software_store: logiciels            # market store selling licence offers
    hourly_rate: 6000                    # default rate of a quote line, in cents
    low_balance_minutes: 120             # below this, forge:hours:low-balance reminds the client
    contact_email: '%env(MAILER_CONTACT)%'   # where quote requests are mailed
# config/packages/git.yaml: open each client their own repositories
git:
    access_role: ROLE_USER
    repository_attribute: GIT_VIEW       # Base\Forge\Security\Voter\GitRepositoryVoter

Every project and piece of software with a repository shows up in git-bundle's viewer on its own, through Base\Forge\Git\ForgeRepositoryProvider. The bundle also needs an nginx internal location for the archives:

location /_protected/forge/ {
    internal;
    alias /srv/app/var/storage/forge/;
}

How a purchase is delivered

Base\Marketplace\Service\Checkout::confirm() dispatches OrderPaidEvent, and Base\Forge\EventSubscriber\OrderPaidSubscriber delivers the order:

Product Delivered
HourPack minutes × quantity credited to the buyer's ledger
LicenseOffer one License per unit (seats, duration and updates taken from the offer)
a quote's own HourPack its hours credited, and the quote marked paid

Delivery is idempotent per order reference. Bank transfers (the manual gateway) stay pending until someone in the admin posts to forge_admin_order_paid, which confirms the order.

Licence keys (glk_…) are generated by their owner from /compte/licences and shown once. Only their SHA-256 is stored.

Commands

Command What it does Suggested cron
forge:release:sync [slug…] fetch the repositories, turn new version tags into releases and build their zip hourly
forge:license:expire mark the licences past their expiry as expired daily
forge:hours:low-balance [--dry-run] e-mail the clients whose support hours run low weekly

Routes

Path Name
/telechargements, /telechargements/{slug} forge_downloads, forge_software
/telechargements/{slug}/{version} forge_download (checks the licence, redirects to a signed URL)
/telechargements/fichier/{id}/{filename} forge_download_file (signed)
/support, /support/devis forge_shop, forge_quote_request
/devis/{token}, /devis/{token}/accepter forge_quote, forge_quote_accept
/compte/licences forge_account_licenses
/composer/packages.json forge_composer_packages
/admin/forge/… release build, quote send, order paid

The templates extend the host's layout1.html.twig, as base-bundle-market's do. They use forge-* classes for the host to style, and can be overridden in templates/bundles/ForgeBundle/.

Tests

vendor/bin/phpunit   # standalone, or from a host: vendor/bin/phpunit -c vendor/omnibase/forge

Licence

LGPL-3.0-or-later.