Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deployer/dev/task/sync.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
if (host('stage')->get('labels')['type'] === 'feature-branch-deployment') {
on(host('stage'), function () {
$currentBranch = runLocally('git branch --show-current');
$target = !is_null(input()->getOption('feature')) ? input()->getOption('feature') : askChoice('Please select a sync origin', array_merge(
$target = featureRequested() ? input()->getOption('feature') : askChoice('Please select a sync origin', array_merge(
["[current] ($currentBranch)", "[prod]"],
array_map(function ($array) {
return $array[2];
Expand Down
16 changes: 11 additions & 5 deletions deployer/feature/task/deploy.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@
* Default extensions for deploy tasks
*/

before('rollback', 'feature:init');
/*
* deploy:info resolves {{release_name}} and deployer caches it for the rest of the
* run. Without this hook the counter is read from the base path and the cached name
* then collides in deploy:release, so the feature instance has to exist by now.
*/
before('deploy:info', 'feature:init');

before('rollback', 'feature:select');
before('deploy:unlock', 'feature:init');
before('feature:sync', 'feature:init');
before('deploy:setup', 'feature:setup');
Expand All @@ -16,7 +23,6 @@
before('feature:sync', 'feature:wait_for_database');
before('deploy:database:update', 'feature:wait_for_database');
after('deploy:symlink', 'feature:urlshortener');
before('feature:sync', 'feature:init');
before('debug:db', 'feature:init');
before('debug:ssh', 'feature:init');
before('debug:log:app', 'feature:init');
before('debug:db', 'feature:select');
before('debug:ssh', 'feature:select');
before('debug:log:app', 'feature:select');
15 changes: 14 additions & 1 deletion deployer/feature/task/feature_init.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,26 @@

task('feature:init', function () {
checkVerbosity();
if (!featureRequested()) {
debug('No feature given, staying on the base instance');
return;
}
// extend deploy path / public url
initFeature();
})
->select('type=feature-branch-deployment')
->once()
->desc('Initialize a feature branch');

task('feature:select', function () {
checkVerbosity();
// extend deploy path / public url, asking for the feature if none was given
initFeature();
})
->select('type=feature-branch-deployment')
->once()
->desc('Select a feature branch and initialize it');


/**
* Initialize a feature branch
Expand All @@ -36,7 +49,7 @@ function initFeature(?string $feature = null): ?string

prepareDeployerConfiguration();
// use feature variable or feature input option or ask for feature branch
$feature = $feature ?: (!is_null(input()->getOption('feature')) ? input()->getOption('feature') : askChoice('Please select a feature branch', array_map(function ($array) {
$feature = $feature ?: (featureRequested() ? input()->getOption('feature') : askChoice('Please select a feature branch', array_map(function ($array) {
Comment thread
konradmichalik marked this conversation as resolved.
Outdated
return $array[2];
}, listFeatureInstances())));
set('feature', $feature);
Expand Down
2 changes: 1 addition & 1 deletion deployer/feature/task/feature_notify.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

task('feature:notify', function () {

if ((has('feature_setup') && !get('feature_setup')) || !input()->getOption('feature')) return;
if ((has('feature_setup') && !get('feature_setup')) || !featureRequested()) return;
checkVerbosity();

set('public_url', get('public_urls')[0]);
Expand Down
4 changes: 3 additions & 1 deletion deployer/feature/task/feature_setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
require_once('url_shortener.php');

task('feature:setup', function () {
if (!input()->hasOption('feature')) {
// Without a feature we are deploying the base instance and must not touch any
// feature scaffolding — renderRemoteTemplates() would overwrite its .env.
if (!featureRequested()) {
return;
}
checkVerbosity();
Expand Down
4 changes: 2 additions & 2 deletions deployer/feature/task/feature_sync.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ function resolveDatabaseHostToIp(string $hostname): void


task('feature:wait_for_database', function () {
if ((has('feature_setup') && !get('feature_setup')) || !input()->getOption('feature')) return;
if ((has('feature_setup') && !get('feature_setup')) || !featureRequested()) return;
waitForDatabaseHost();
})
->select('type=feature-branch-deployment')
Expand All @@ -113,7 +113,7 @@ function resolveDatabaseHostToIp(string $hostname): void

task('feature:sync', function () {

if ((has('feature_setup') && !get('feature_setup')) || !input()->getOption('feature')) return;
if ((has('feature_setup') && !get('feature_setup')) || !featureRequested()) return;

$feature = initFeature();
$synced = false;
Expand Down
2 changes: 1 addition & 1 deletion deployer/feature/task/url_shortener.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

tasK('feature:urlshortener', function () {
Comment thread
konradmichalik marked this conversation as resolved.
Outdated

if (!input()->getOption('feature')) {
if (!featureRequested()) {
return;
}
if (!isUrlShortener()) {
Expand Down
14 changes: 14 additions & 0 deletions deployer/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,20 @@ function checkVerbosity(): void
}
}

/**
* Whether a feature instance was addressed via --feature.
*
* An empty --feature= counts as absent: it would otherwise resolve to the base
* instance path and let the feature scaffolding write into the reference stage.
* The option itself only exists once the feature recipe is loaded, hence hasOption().
*
* @return bool
*/
function featureRequested(): bool
{
return input()->hasOption('feature') && !empty(input()->getOption('feature'));
Comment thread
konradmichalik marked this conversation as resolved.
Outdated
}
Comment thread
konradmichalik marked this conversation as resolved.

/**
* Extend the deployer configuration with available environment variables (starting with "DEPLOYER_CONFIG_"):
*
Expand Down
8 changes: 3 additions & 5 deletions docs/FEATURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,7 @@ The `feature:setup` command represent the initialization of a new feature branch
$ vendor/bin/dep feature:setup stage --feature=TEST-01
```

This task should be declared to run at first within your deploy task:

```php
before('deploy:info', 'feature:setup');
```
The recipe already wires this task into the deploy flow, together with a `feature:init` before `deploy:info`. That ordering matters: `deploy:info` resolves `{{release_name}}` and deployer caches the result for the rest of the run, so the feature instance has to be known before it runs. Do not hook `feature:setup` any earlier yourself.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

If the application needs to setup additional configuration files for e.g. storing the database credentials, use the feature templates to provide this kind of dynamic setup. For example the TYPO3 setup with a `.env` file:

Expand Down Expand Up @@ -88,6 +84,8 @@ You can extend these list be providing more environment variables starting with
> ```php
> before('deploy:rollback', 'feature:init');
> ```
>
> `feature:init` is a no-op without `--feature`, so the command keeps operating on the base instance. Use `feature:select` instead if the command should offer an interactive choice between the existing feature instances when `--feature` is omitted.

### Deletion

Expand Down