### Enable multi-tenancy at runtime Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Example of enabling multi-tenancy at runtime by setting the tenancy config values, including a resolver that returns the current tenant ID. ```php // In a service provider or middleware config(['satis.tenancy.enabled' => true]); config(['satis.tenancy.model' => \App\Models\Team::class]); config(['satis.tenancy.foreign_key' => 'team_id']); config(['satis.tenancy.resolver' => fn () => auth()->user()?->current_team_id]); ``` -------------------------------- ### Install laravel-satis with Composer Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Installs the laravel-satis package via Composer. ```bash composer require jeffersongoncalves/laravel-satis ``` -------------------------------- ### Pest Test Setup Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Set up Pest to use the package's TestCase for Feature and Unit tests. This enables testing with Orchestra Testbench and SQLite in-memory database. ```php use JeffersonGoncalves\LaravelSatis\Tests\TestCase; uses(TestCase::class)->in('Feature', 'Unit'); ``` -------------------------------- ### Publish and run migrations Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Publishes the package migrations and runs them to set up the database tables. ```bash php artisan vendor:publish --tag="satis-migrations" php artisan migrate ``` -------------------------------- ### Manage credentials, packages, and tokens with ModelResolver Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Shows how to programmatically create credentials, packages, tokens, and assign packages to tokens using ModelResolver. Includes validation of a credential via the ValidateCredential action, which returns a success array. ```php use JeffersonGoncalves\LaravelSatis\Support\ModelResolver; // Create a credential $credentialModel = ModelResolver::credential(); $credential = $credentialModel::create([ 'name' => 'My Private Repo', 'url' => 'https://repo.example.com', 'email' => 'user', 'password' => 'secret', ]); // Create a package using the credential $packageModel = ModelResolver::package(); $package = $packageModel::create([ 'name' => 'vendor/package-name', 'type' => 'composer', 'credential_id' => $credential->id, ]); // Create a GitHub credential and package $githubCredential = $credentialModel::create([ 'name' => 'GitHub', 'url' => 'https://github.com/vendor/repo.git', 'email' => 'github-user', 'password' => 'github-token', ]); $githubPackage = $packageModel::create([ 'name' => 'vendor/github-package', 'type' => 'github', 'credential_id' => $githubCredential->id, ]); // Create a dev package (reusing same credential) $devPackage = $packageModel::create([ 'name' => 'vendor/dev-tool', 'type' => 'composer', 'credential_id' => $credential->id, 'is_dev' => true, ]); // Validate a credential $result = app(\JeffersonGoncalves\LaravelSatis\Actions\ValidateCredential::class) ->execute($credential); // $result = ['success' => true, 'message' => 'Credential validated successfully.'] // Create a token $tokenModel = ModelResolver::token(); $token = $tokenModel::create([ 'name' => 'My Token', 'email' => 'user@example.com', ]); // Assign packages to token $token->packages()->attach($package->id); ``` -------------------------------- ### SatisConfig fluent builder and setPackages() Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Use the fluent builder to create a Satis configuration. The first part builds a config with homepage, notifyBatch, httpBasic, repository, and require. The second part shows setPackages() for automatic credential handling, including conflict detection, deduplication, and auth headers. ```php use JeffersonGoncalves\LaravelSatis\Support\SatisConfig; use JeffersonGoncalves\LaravelSatis\Data\PackageData; use JeffersonGoncalves\LaravelSatis\Data\RepositoryData; // Fluent builder API $config = SatisConfig::make() ->homepage('https://satis.example.com') ->notifyBatch(route('composer.downloads')) ->httpBasic('repo.example.com', 'user', 'pass') ->repository(new RepositoryData(name: 'vendor/pkg', type: 'composer', url: 'https://repo.example.com')) ->require(new PackageData(name: 'vendor/pkg')); $json = $config->toJson(); echo (string) $config; // Implements Stringable // Or use setPackages() for automatic credential handling $config = SatisConfig::make() ->setPackages($packages); // Handles conflict detection, deduplication, auth headers ``` -------------------------------- ### Run Satis build and maintenance artisan commands Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Lists the artisan commands for building, validating, sanitizing, and cleaning Satis repositories. Includes options for tenant and token filtering, and a --force flag to skip confirmation. ```bash # Build all packages (tenant-based) php artisan satis:build # Build for a specific tenant php artisan satis:build --tenant=1 # Build per token (all tokens with packages) php artisan satis:token-build # Build for a specific token php artisan satis:token-build --token=5 # Validate credentials and trigger rebuilds if needed php artisan satis:validate # Process dependencies php artisan dependency:packages # Remove credentials from Satis JSON files php artisan satis:sanitize # Clean all Satis builds from storage php artisan satis:clean # Force clean without confirmation php artisan satis:clean --force ``` -------------------------------- ### Storage configuration Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Configures the storage disk and path for the package. ```php 'storage_disk' => 'local', 'storage_path' => 'satis', ``` -------------------------------- ### Dispatch SyncTenantPackages and SyncTokenPackages Jobs Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Shows how to manually dispatch the build jobs for a specific tenant or token. Uses the dispatch method on the job classes. ```php use JeffersonGoncalves\LaravelSatis\Jobs\SyncTenantPackages; use JeffersonGoncalves\LaravelSatis\Jobs\SyncTokenPackages; // Build for specific tenant SyncTenantPackages::dispatch($tenantId); // Build for specific token SyncTokenPackages::dispatch($token); ``` -------------------------------- ### Publish the config file Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Publishes the configuration file (config/satis.php) for customization. ```bash php artisan vendor:publish --tag="satis-config" ``` -------------------------------- ### Authenticate Composer with token Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Authenticates Composer to the private repository using the token as a password with any username. Run after adding the repository configuration. ```bash composer config http-basic.your-app.com/satis "any-username" "your-token-here" ``` -------------------------------- ### Satis Build Pipeline Diagram Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md ASCII diagram of the build pipeline showing the sequence of operations: grouping by credential, building satis.json, running satis build with retry, merging snapshots, sanitizing output, and syncing tokens. ```text satis:build command └─> SyncTenantPackages (timeout: 86400s) ├─> Groups packages by credential_id ├─> For each credential group: │ ├─> Builds satis.json with inline auth URLs (RFC 3986) │ ├─> Writes auth.json for Composer home │ ├─> Runs `php satis build` with retry (max 3, backoff on 429) │ └─> Saves snapshot of packages.json ├─> Merges all snapshots via MergeSatisPackagesJson ├─> Sanitizes output (removes inline credentials) └─> SyncTokenPackages (per token, same grouping/retry logic) ``` -------------------------------- ### Create a token and associate packages Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Creates a token with the given name and email. The token value is auto-generated by TokenObserver, and a SyncTokenPackages job is auto-dispatched. Packages can be associated using the packages() relationship. ```php use JeffersonGoncalves\LaravelSatis\Support\ModelResolver; $token = ModelResolver::token()::create([ 'name' => 'CI/CD Token', 'email' => 'dev@example.com', ]); // token value (64-char) is auto-generated by TokenObserver // SyncTokenPackages job is auto-dispatched on creation // Associate packages with token $token->packages()->attach([$package->id]); ``` -------------------------------- ### Composer config for Satis repository with HTTP Basic auth Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Configure Composer to use the Satis repository with HTTP Basic authentication. The first command adds the repository, the second sets the credentials (empty username, token as password). ```bash # Composer usage in composer.json composer config repositories.private composer https://example.com/satis composer config http-basic.example.com "" "TOKEN_VALUE_HERE" ``` -------------------------------- ### Configure Composer client repository Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Composer client configuration to add the private Satis repository. Clients must include this in their composer.json to use the built packages. ```json { "repositories": [ { "type": "composer", "url": "https://your-app.com/satis" } ] } ``` -------------------------------- ### Enable multi-tenancy in config/satis.php Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Enable multi-tenancy in the Satis configuration. The resolver returns the tenant ID from the authenticated user. The HasTenancy trait on models adds global scope, sets tenant_id on creation, and provides a tenant() relationship. ```php // config/satis.php 'tenancy' => [ 'enabled' => true, 'model' => \App\Models\Tenant::class, 'foreign_key' => 'tenant_id', 'ownership_relationship' => null, 'resolver' => fn () => auth()->user()?->tenant_id, ], ``` -------------------------------- ### Process Package Dependencies Action Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Instantiates ProcessPackageDependency and executes it with a package release and require array. ```php use JeffersonGoncalves\LaravelSatis\Actions\ProcessPackageDependency; $action = new ProcessPackageDependency(); $action->execute($packageRelease, $requireArray); ``` -------------------------------- ### Merge Satis Snapshots Action Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Instantiates MergeSatisPackagesJson and calls handle with output directory, snapshot paths, and disk. Merges packages, available-packages, and includes from multiple snapshots. ```php use JeffersonGoncalves\LaravelSatis\Actions\MergeSatisPackagesJson; $action = new MergeSatisPackagesJson(); $action->handle($outputDir, $snapshotPaths, $disk); // Merges packages, available-packages, includes from multiple snapshots ``` -------------------------------- ### Create a package with ModelResolver and PackageType Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Creates a package with the given name, type, and credential_id. The webhook_secret and reference fields are auto-generated by PackageObserver. ```php use JeffersonGoncalves\LaravelSatis\Enums\PackageType; use JeffersonGoncalves\LaravelSatis\Support\ModelResolver; $package = ModelResolver::package()::create([ 'name' => 'vendor/package-name', 'type' => PackageType::Composer, 'credential_id' => $credential->id, // required FK ]); // webhook_secret (64 chars) and reference (32 chars) are auto-generated by PackageObserver ``` -------------------------------- ### Upgrade commands for v2.0 Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Commands to update the package, publish migrations, and run them. The first command requires the package version ^2.0. The second publishes migration files with the specified tag. The third runs the migrations. ```bash composer require jeffersongoncalves/laravel-satis:^2.0 ``` ```bash php artisan vendor:publish --tag="satis-migrations" ``` ```bash php artisan migrate ``` -------------------------------- ### Run tests with composer test Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Run this command in a terminal to execute the project's test suite using Composer. ```bash composer test ``` -------------------------------- ### Queue configuration Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Queue configuration. Null connection and queue name use the default. Timeout is set to 86400 seconds (24 hours). ```php 'queue' => [ 'connection' => null, // null = default connection 'queue_name' => null, // null = default queue 'timeout' => 86400, // 24 hours (in seconds) ], ``` -------------------------------- ### Migrate package credentials to credentials table Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Migrates existing package credentials to the new credentials table before running migrations. Creates a Credential record for each unique URL and username combination, then updates the satis_packages table with the new credential_id. Must be run before the migrations. ```php use JeffersonGoncalves\LaravelSatis\Models\Credential; $packages = DB::table('satis_packages')->get(); $credentialMap = []; foreach ($packages as $package) { $key = $package->url . '|' . $package->username; if (! isset($credentialMap[$key])) { $credential = Credential::create([ 'name' => parse_url($package->url, PHP_URL_HOST) ?? $package->url, 'url' => $package->url, 'email' => $package->username, 'password' => $package->password, 'is_validated' => $package->is_credentials_validated, 'validated_at' => $package->credentials_validated_at, ]); $credentialMap[$key] = $credential->id; } DB::table('satis_packages') ->where('id', $package->id) ->update(['credential_id' => $credentialMap[$key]]); } ``` -------------------------------- ### Sanitize Satis Output Action Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Instantiates SanitizeSatisPackages and calls sanitizeDirectory with build path and disk. Removes transport-options and inline credentials from JSON files. ```php use JeffersonGoncalves\LaravelSatis\Actions\SanitizeSatisPackages; $sanitizer = new SanitizeSatisPackages(); $sanitizer->sanitizeDirectory($buildPath, $disk); // Removes transport-options and inline credentials from JSON files ``` -------------------------------- ### Run Pest Tests Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Run the test suite using Pest. This command executes all tests in the Feature and Unit directories. ```bash php vendor/bin/pest ``` -------------------------------- ### Multi-tenancy configuration Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Default multi-tenancy configuration. The resolver accepts any callable that returns the current tenant ID. ```php 'tenancy' => [ 'enabled' => false, 'model' => null, 'foreign_key' => null, 'ownership_relationship' => null, 'resolver' => null, // callable that returns the current tenant ID ], ``` -------------------------------- ### Routes configuration Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Route configuration for API and Composer endpoints, including middleware. ```php 'routes' => [ 'api_prefix' => 'api/satis', 'composer_prefix' => 'satis', 'middleware' => ['api'], ], ``` -------------------------------- ### Create RepositoryData DTO Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Instantiates a RepositoryData object with name, type, and URL. Used to define a repository source for Satis. ```php use JeffersonGoncalves\LaravelSatis\Data\RepositoryData; new RepositoryData(name: 'vendor/pkg', type: 'composer', url: 'https://repo.example.com'); ``` -------------------------------- ### Validate Package Credentials Action Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Instantiates ValidatePackageCredentials and executes it with a package. Returns a boolean, using the package's credential property. ```php use JeffersonGoncalves\LaravelSatis\Actions\ValidatePackageCredentials; $action = new ValidatePackageCredentials(); $isValid = $action->execute($package); // Returns bool, uses $package->credential ``` -------------------------------- ### Table prefix configuration Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Sets the table prefix. Set to null to use table names without a prefix. ```php 'table_prefix' => 'satis_', ``` -------------------------------- ### Create a credential with ModelResolver Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Creates a credential with the given fields. The is_validated and validated_at fields default to false and null respectively. ```php use JeffersonGoncalves\LaravelSatis\Support\ModelResolver; $credential = ModelResolver::credential()::create([ 'name' => 'My Private Repo', 'url' => 'https://repo.example.com', 'email' => 'user', 'password' => 'secret', ]); // is_validated defaults to false, validated_at defaults to null ``` -------------------------------- ### Create PackageData DTO Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Instantiates a PackageData object with name and version. Used to represent a package in the Satis configuration. ```php use JeffersonGoncalves\LaravelSatis\Data\PackageData; new PackageData(name: 'vendor/pkg', version: '*'); ``` -------------------------------- ### Custom models configuration Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Override any model to extend the default behavior. ```php 'models' => [ 'credential' => \App\Models\SatisCredential::class, 'package' => \App\Models\SatisPackage::class, 'token' => \App\Models\SatisToken::class, // ... ], ``` -------------------------------- ### Configure minimum-stability in composer.json Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Required in the consuming application's composer.json to allow development packages because the package depends on composer/satis at version 3.x-dev, which has no stable release yet. ```json { "minimum-stability": "dev", "prefer-stable": true } ``` -------------------------------- ### PackageType enum values Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Defines the available package types: Composer for Composer repositories with packages.json, and Github for GitHub VCS repositories. ```php use JeffersonGoncalves\LaravelSatis\Enums\PackageType; PackageType::Composer // Composer repository with packages.json PackageType::Github // GitHub VCS repository ``` -------------------------------- ### Scheduling configuration Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Scheduling configuration for various tasks. Values can be any Laravel Schedule method or null. ```php 'schedule' => [ 'build' => 'weekly', // any Laravel Schedule method or null 'token_build' => 'weekly', 'validate' => 'hourly', 'sanitize' => 'daily', 'dependencies' => 'weekly', ], ``` -------------------------------- ### Model Override Configuration Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Override default models by mapping them in the 'models' configuration array. Custom models must implement the corresponding contract interface (e.g., CredentialContract, PackageContract). ```php // config/satis.php 'models' => [ 'credential' => \App\Models\CustomCredential::class, 'package' => \App\Models\CustomPackage::class, // ... ], ``` -------------------------------- ### Validate Credential Action Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Executes the ValidateCredential action via the container. Returns an array with success flag and message. ```php use JeffersonGoncalves\LaravelSatis\Actions\ValidateCredential; $result = app(ValidateCredential::class)->execute($credential); // ['success' => true, 'message' => 'Credential validated successfully.'] ``` -------------------------------- ### GitHub webhook endpoint Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/README.md Webhook URL for GitHub events. Each package has a unique reference. Set Content type to application/json and optionally configure a Secret using the package's webhook_secret. Supported events: push, release, create; others are ignored with HTTP 200. ```http POST /api/satis/webhooks/github/{package-reference} ``` -------------------------------- ### GitHub Webhook Endpoint Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Use this endpoint to trigger a package rebuild via GitHub webhook. The URL includes the package's auto-generated reference. The webhook validates the HMAC-SHA256 signature using the package's webhook_secret before dispatching a rebuild. ```http POST /api/satis/webhooks/github/{package.reference} ``` -------------------------------- ### ModelResolver usage for models Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Use ModelResolver to reference models instead of hardcoding class names. This ensures compatibility with custom model implementations. ```php use JeffersonGoncalves\LaravelSatis\Support\ModelResolver; // Correct $credential = ModelResolver::credential()::create([...]); $package = ModelResolver::package()::create([...]); $token = ModelResolver::token()::find($id); // Incorrect - don't do this $package = new Package(); ``` -------------------------------- ### Validate a credential with ValidateCredential action Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Validates a credential using the ValidateCredential action. Returns an array with success and message keys, and updates the credential's is_validated and validated_at fields. ```php use JeffersonGoncalves\LaravelSatis\Actions\ValidateCredential; $result = app(ValidateCredential::class)->execute($credential); // Returns: ['success' => bool, 'message' => string] // Updates is_validated and validated_at on the credential ``` -------------------------------- ### DependencyType enum values Source: https://github.com/jeffersongoncalves/laravel-satis/blob/main/resources/boost/skills/laravel-satis-development/SKILL.md Defines the dependency types: Public for packages that exist on Packagist, and Private for custom/private packages. ```php use JeffersonGoncalves\LaravelSatis\Enums\DependencyType; DependencyType::Public // Exists on Packagist DependencyType::Private // Custom/private package ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.