Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 6 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ jobs:
git config user.name github-actions[bot]
git config user.email github-actions[bot]@users.noreply.github.com
git tag -a "v${{ steps.get_version.outputs.version }}" -m "Release version ${{ steps.get_version.outputs.version }}"

git push origin "v${{ steps.get_version.outputs.version }}"

- name: Extract changelog for version
id: changelog
if: steps.check_tag.outputs.exists == 'false'
Expand Down Expand Up @@ -82,15 +83,16 @@ jobs:
echo "changelog<<EOF" >> $GITHUB_OUTPUT
echo "$CHANGELOG" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

- name: Create Release
if: steps.check_tag.outputs.exists == 'false'
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.get_version.outputs.version }}
name: ${{ steps.get_version.outputs.version }}
tag_name: v${{ steps.get_version.outputs.version }}
name: v${{ steps.get_version.outputs.version }}
body: |
${{ steps.changelog.outputs.changelog }}
draft: false
prerelease: false
token: ${{ secrets.GITHUB_TOKEN }}

18 changes: 18 additions & 0 deletions doc/User-Guide/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,24 @@ The 1st connection in the `"connections"` array is the **default**, and does not
}
```

### Storage Configuration

Controls the shared storage path used by `app()->getSharedStoragePath()`.

```json
{
"storage": {
"shared": "${env:SHARED_STORAGE_PATH}"
}
}
```

| Key | Description |
|-----|-------------|
| `shared` | Base path for shared storage. The framework appends `/{environment}/{appCode}` to form the final path. Leave empty or omit to use local `{basePath}/storage` instead. |

See [Storage Folders](Storage-folders.md) for full details.

### Factory Configuration

```json
Expand Down
60 changes: 53 additions & 7 deletions doc/User-Guide/Storage-folders.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,65 @@
- [1. Storage folders](#1-storage-folders)
- [1.1 getStoragePath()](#11-getstoragepath)
- [1.2 getSharedStoragePath()](#12-getsharedstoragepath)
- [1.3 Configuration](#13-configuration)

# 1. Storage folders
There are two methods to obtain storage folders. The folders have different meaning and usage scenarios.

Two storage paths are available. They serve different purposes and are suited to different use cases.

## 1.1 getStoragePath()
The files in this folder are considered temporary and instance specific. They exist only for as long as the instance exists.

Calling `app()->getStoragePath()` obtains the local storage folder `/<path_to_app>/app/src/storage`.
The local storage path is instance-specific. It is intended for temporary files that do not need to survive a restart or be shared with other instances.

```php
$path = app()->getStoragePath();
// e.g. /var/www/myapp/storage
```

The path resolves to `{basePath}/storage` where `basePath` is the root directory passed to the `Application` constructor.

## 1.2 getSharedStoragePath()
Files in this folder can be considered persistent as they are shared and accessible between all instances of the service.

Calling `app()->getSharedStoragePath()` obtains the configured path in the config file (`storage.shared`) and appends
the `envirnoment` and `application.code` to it to make it unique among all services.
The shared storage path is intended for persistent files that must be accessible across all instances of the application (e.g. in a load-balanced or multi-container environment).

```php
$path = app()->getSharedStoragePath();
// e.g. /mnt/shared/dev/myapp
```

The resolved path depends on the `storage.shared` config key:

| `storage.shared` set? | Resolved path |
|-----------------------|---------------|
| Yes | `{storage.shared}/{environment}/{appCode}` |
| No (empty/absent) | Falls back to `getStoragePath()` |

When the resolved path does not exist, the framework attempts to create it automatically. If creation fails, a warning is logged and the path remains as configured.

## 1.3 Configuration

Add a `storage` section to your `config-{env}.json` to enable shared storage:

```json
"storage": {
"shared": "/mnt/shared"
}
```

With `appCode = myapp` and `environment = prod`, the resolved path becomes `/mnt/shared/prod/myapp`.

The value supports environment variable expansion:

```json
"storage": {
"shared": "${env:SHARED_STORAGE_PATH}"
}
```

Omit the key (or set it to an empty string) to use local storage only:

> **NOTE** If this folder is not found when the application is run() it is set to the same as `getStoragePath` to maintain a folder.
```json
"storage": {
"shared": ""
}
```
11 changes: 10 additions & 1 deletion src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,16 @@ class Application extends AbstractBaseClass implements ApplicationInterface
protected string $storagePath;

/**
* Path to shared storage
* Path to shared storage.
*
* This is either the path defined in `config('storage.shared')` or the local
* storage path if not set. The default path is `{$basePath}/storage/shared/{$environment}/{$appCode}`
* where `$environment` and `$appCode` are extracted from the config file.
*
* This allows multiple SPIN apps running on the same server/host to share the same storage folder if needed.
*
* Note: If the shared path does not exist, this will become the same as storage path.
*
* @var mixed
*/
protected mixed $sharedStoragePath;
Expand Down
12 changes: 9 additions & 3 deletions src/ApplicationInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,15 @@ public function getConfigPath(): string;
public function getStoragePath(): string;

/**
* Gets the full path to the configured shared storage path.
* If the config does not contain an entry for the shared storage, the result is the same
* as `getStoragePath()`
* Path to shared storage.
*
* This is either the path defined in `config('storage.shared')` or the local
* storage path if not set. The default path is `{$basePath}/storage/shared/{$environment}/{$appCode}`
* where `$environment` and `$appCode` are extracted from the config file.
*
* This allows multiple SPIN apps running on the same server/host to share the same storage folder if needed.
*
* Note: If the shared path does not exist, this will become the same as storage path.
*
* @return string The shared storage path
*/
Expand Down