standard-library/sdk-application

Maintainers

Package info

gitlab.com/php-standard-library/release-packages/sdk-application

Issues

Type:standard-library-sdk

pkg:composer/standard-library/sdk-application

Transparency log

Statistics

Installs: 36

Dependents: 0

Suggesters: 0

Stars: 0

1.0.30 2026-08-03 14:45 UTC

This package is auto-updated.

Last update: 2026-08-04 15:38:47 UTC


README

Build and deployment tooling for applications built on top of the PHP Standard Library: assembling a deployable build directory, a Deployer-style (releases/shared/current) rsync-over-ssh deploy, and a temporary SSH key installer for CI. Config parsing uses symfony/yaml, process/filesystem handling uses symfony/process and symfony/filesystem; deploy itself shells out directly to the rsync/ssh/ssh-keygen binaries.

{
  "require-dev": {
    "standard-library/sdk-application": "^1.0"
  }
}

Commands

CommandPurpose
bin/sdk app:buildAssemble a deployable build directory (composer install --no-dev, plus optional build steps).
bin/sdk deploy:run <environment>Rsync the configured source directory to the environment's host/path.
bin/sdk deploy:set-temporary-ssh-key <environment>Write a temporary SSH key/known_hosts entry from environment variables.

All three are bin/sdk commands (see standard-library/sdk's README) — run any of them in Docker with --docker (e.g. bin/sdk deploy:run production --docker); the deploy commands additionally mount the host's ~/.ssh into the container, so a key written by deploy:set-temporary-ssh-key is still there for a later deploy:run run.

Each command reads config-dev.yaml under the section keyed by its own fully qualified class name (see standard-library/sdk's Console\Command base class). deploy:run and deploy:set-temporary-ssh-key need the same per-environment data, so define it once via a YAML anchor and merge it into both sections.

config-dev.yaml

'StandardLibrary\Sdk\Application\Console\Command\BuildCommand':
  output: artifacts/build
  dirs:
    - src
    - public
  files:
    - composer.json
    - composer.lock
  exclude:
    - vendor/bin
  steps:
    - App\Build\FrontendBuildStep

.deploy: &deploy
  production:
    host: example.com
    user: deploy
    port: 22
    path: /var/www/example
    source: artifacts/build
    exclude:
      - .env.local
    writable-dirs:
      - var/cache
    shared-dirs:
      - var/uploads
    shared-files:
      - .env
    keep-releases: 5
    key:
      host: "example.com ssh-ed25519 AAAA..."
      public: "ssh-ed25519 AAAA... deploy@ci"

'StandardLibrary\Sdk\Application\Console\Command\DeployCommand':
  <<: *deploy

'StandardLibrary\Sdk\Application\Console\Command\DeploySetTemporarySshKeyCommand':
  <<: *deploy

build

  • output is the directory (relative to the project root) the finished build is moved to; defaults to artifacts/build — matching deploy.<environment>.source above.
  • dirs/files are optional. If both are empty, bin/sdk app:build git clones the project's own .git into the build directory (i.e. exactly the committed tree). If either is set, only the listed directories/files are extracted via git archive, so uncommitted or gitignored files can never end up in the build even when only part of the project is selected.
  • exclude is an optional list of paths (relative to the build directory) removed as the last step before the result is moved to output — after composer install and all steps have run, so it can also strip things they produced (e.g. dev tooling left behind under vendor/bin), not just files that were already there when the project was copied.
  • steps is an optional list of class names implementing StandardLibrary\Sdk\Application\Build\Step\BuildStep, run in order after the composer install. This is the extension point for things this package deliberately doesn't ship — frontend asset compilation, CMS-specific setup, etc. — supplied by another package on the classpath. Each step is instantiated with no constructor arguments and receives a BuildContext (project root, build directory, logger).

bin/sdk app:build

  1. Copies the project into a temporary build directory (see dirs/files above).
  2. Writes a REVISION file containing the project's current git rev-parse HEAD.
  3. Runs composer install --no-dev --no-interaction in it.
  4. Runs each configured steps entry.
  5. Removes each configured exclude path.
  6. Atomically moves the result to output (removing any previous build there first).

deploy

  • host, user, path, source are required. port defaults to 22.
  • source is the local directory (relative to the project root) that gets rsynced; .git is always excluded in addition to any exclude entries.
  • path is the deployment root, not the web-served directory — see the release layout below.
  • writable-dirs are chmod -R a+w'd inside the new release after the sync.
  • shared-dirs/shared-files persist across deploys (uploads, logs, .env, ...) — see below.
  • keep-releases is how many past releases to retain; defaults to 5.
  • key.host/key.public are only used by deploy:set-temporary-ssh-key.

The <environment> argument tab-completes (via bin/sdk's shell completion — see standard-library/sdk's README) to whatever environment keys are configured in each command's own section above.

bin/sdk deploy:run <environment>

Deployer-style releases/shared/current layout under path, not a direct in-place sync:

path/
  releases/
    20260801120000/   - one full rsync per deploy, named by timestamp
    ...
  shared/              - persists across every deploy
  current -> releases/20260801120000

Each run:

  1. Creates a new path/releases/<timestamp>/ directory and rsyncs source into it (rsync -avz --delete over the given port; .git and exclude entries are always skipped).
  2. For each shared-dirs/shared-files entry: ensures it exists under path/shared/ (bootstrapping it from the freshly synced release's own copy on the very first deploy, if present), removes the copy that just got synced into the new release, and symlinks it from path/shared/ instead — so uploads, logs, or a server-side .env survive every subsequent deploy untouched.
  3. Applies writable-dirs inside the new release.
  4. Atomically flips path/current to point at the new release (ln -sfn).
  5. Prunes old releases beyond keep-releases.

Because each deploy syncs into a brand-new directory and only swaps current at the very end, the live site (whatever serves from path/current) is never left mid-sync — unlike a direct in-place rsync.

bin/sdk deploy:set-temporary-ssh-key <environment>

Writes ~/.ssh/known_hosts (from key.host), ~/.ssh/id_rsa.pub (from key.public), and ~/.ssh/id_rsa (from the KEY_<ENVIRONMENT> environment variable, e.g. KEY_PRODUCTION) if they don't already exist. If a PASSPHRASE_<ENVIRONMENT> environment variable is set, it re-encrypts the private key with that passphrase via ssh-keygen.