Skip to content
Open
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: 10 additions & 0 deletions .devcontainer/create.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

### Add ssh-keyscan to known_hosts
mkdir -p /home/vscode/.ssh
chmod 700 /home/vscode/.ssh
ssh-keyscan github.com >>/home/vscode/.ssh/known_hosts

### Ensure correct access rights
sudo chown -Rf vscode:vscode ${containerWorkspaceFolder:-.}/* ${containerWorkspaceFolder:-.}/.*
sudo chmod -Rf 755 ${containerWorkspaceFolder:-.}/* ${containerWorkspaceFolder:-.}/.*
15 changes: 15 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"name": "",
"features": {
"ghcr.io/devcontainers/features/docker-in-docker": {},
"ghcr.io/devcontainers/features/node": "lts",
"ghcr.io/devcontainers/features/php": "8.2",
"ghcr.io/tomgrv/devcontainer-features/githooks": {},
"ghcr.io/tomgrv/devcontainer-features/gitutils": {}
},
"remoteEnv": {},
"postCreateCommand": ".devcontainer/create.sh",
"postStartCommand": ".devcontainer/start.sh",
"customizations": {}
}
9 changes: 9 additions & 0 deletions .devcontainer/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh

### Make sure the workspace folder is owned by the user
git config --global --add safe.directory ${containerWorkspaceFolder:-.}

### Define gpg configuration
if [ -z "$CODESPACES" ]; then
git config --global gpg.program gpg2
fi
8 changes: 8 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
* text=auto eol=lf
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
*.css linguist-vendored
*.scss linguist-vendored
*.js linguist-vendored
*.json merge=json
CHANGELOG.md export-ignore
26 changes: 0 additions & 26 deletions .php_cs

This file was deleted.

1 change: 0 additions & 1 deletion .styleci.yml

This file was deleted.

15 changes: 15 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "⏬ Upd. DevEnv",
"type": "shell",
"command": "npm exec --yes -- tomgrv/devcontainer-features -u",
"presentation": {
"panel": "shared",
"close": true,
"reveal": "always"
}
}
]
}
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!-- @format -->

# Changelog

All notable changes to `klick-deploy` will be documented in this file.

## [Unreleased]

### Added

- **Automatic Crontab Management**: Added support for automatic crontab job configuration using Deployer's crontab contrib package
- `php artisan queue:restart` scheduled every hour to prevent memory leaks
- `php artisan schedule:run` scheduled every minute for Laravel's task scheduler
- Crontab setup runs automatically just before deployment unlock
- Jobs are properly configured to use the current deployment path
- New platform task `platform:crontab` for manual crontab configuration
- New platform task `platform:crontab:remove` for cleaning up crontab jobs

### Changed

- Updated platform.php to include crontab task file
- Enhanced documentation with crontab features

## [1.0.0] - Initial Release

### Features

- Initial klick-deploy package with URL-based deployment configuration
- Support for Laravel deployment strategies
- cPanel integration tasks
- Platform management tasks
- Module activation/deactivation support
- Asset upload functionality
- Environment variable management
- Version setting capabilities
28 changes: 28 additions & 0 deletions actions/clean-history/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# @format

name: 'Cleanup past deployment'
description: 'Remove all past deployments'
branding:
icon: 'check'
color: 'blue'
inputs:
workflows:
description: 'Comma separated list of workflow files to delete'
required: false
default: ''
status:
description: 'Comma separated list of workflow status to delete'
required: false
default: ''
older:
description: 'Specify the number of days to delete workflow runs older than this value'
required: false
default: ''
runs:
using: composite
steps:
- name: Run Delete Script with List
if: ${{ inputs.workflows != '' }}
shell: sh
run: |
${{ github.action_path }}/delete.sh ${{ inputs.older != '' && '-o' }} ${{ inputs.older }} ${{ inputs.workflows != '' && '-w' }} ${{ inputs.workflows }} ${{ inputs.status != '' && '-s' }} ${{ inputs.status }}
69 changes: 69 additions & 0 deletions actions/clean-history/delete.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/bin/sh

# Init default values
older=30
status="failure,cancelled"
repo=$(git config --get remote.origin.url | sed -E 's/.*[:\/]([^\/]+\/[^\.]+)(\.git)?$/\1/')

# handle arguments with getopt
OPTSTRING="w:o:s:r:"
while getopts ${OPTSTRING} opt; do
case ${opt} in
w)
workflows=$(echo ${OPTARG} | tr ',' ' ')
echo "Selected workflow: ${workflows}" >&2
;;
o)
older=${OPTARG}
echo "Select older than: ${older} days" >&2
;;
s)
status=${OPTARG}
echo "Select status: ${status}" >&2
;;
r)
repo=${OPTARG}
echo "Select repository: ${repo}" >&2
;;
:)
echo "Option -${OPTARG} requires an argument." >&2
exit 1
;;
?)
echo "Invalid option: -${OPTARG}." >&2
exit 1
;;
esac
done

if [ -z "$workflows" ]; then
echo "No workflow specified. Listing all workflow runs for $repo..." >&2

# Creates a temporary file to store workflow data.
workflows_temp=$(mktemp)

# Lookup workflow
gh api repos/$repo/actions/workflows | jq -r '.workflows[] | [.id, .path] | @tsv' >$workflows_temp
cat "$workflows_temp"

# Get the list of workflow names that are not successful or failed
workflows_names=$(awk '{print $2}' $workflows_temp | grep -v "main")

# Save a comma separated list of workflow names using basename
workflows=$(echo "$workflows_names" | xargs -I{} basename {} | tr '\n' ' ')
fi

if [ -z "$workflows" ]; then
echo "Nothing to remove" >&2
else
echo "Removing all selected workflows that are not successful or failed" >&2

for workflow in $workflows; do

echo "Deleting <$workflow> history, please wait..." >&2
$(dirname $0)/list.sh -w $workflow -o $older -s $status -r $repo | xargs -I{} gh run delete {}
done
fi

rm -rf $workflows_temp
echo "Done." >&2
48 changes: 48 additions & 0 deletions actions/clean-history/list.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/sh

# Init default values
workflow=""
older=30
status="failure,cancelled"
repo=$(git config --get remote.origin.url | sed -E 's/.*[:\/]([^\/]+\/[^\.]+)(\.git)?$/\1/')

# handle arguments with getopt
OPTSTRING="w:o:s:r:"
while getopts ${OPTSTRING} opt; do
case ${opt} in
w)
workflow=${OPTARG}
echo "Selected workflow: ${workflow}" >&2
;;
o)
older=${OPTARG}
echo "Select older than: ${older} days" >&2
;;
s)
status=${OPTARG}
echo "Select status: ${status}" >&2
;;
r)
repo=${OPTARG}
echo "Select repository: ${repo}" >&2
;;
:)
echo "Option -${OPTARG} requires an argument." >&2
exit 1
;;
?)
echo "Invalid option: -${OPTARG}." >&2
exit 1
;;
esac
done

# Format the status string to be used in jq
status=$(echo $status | tr '[:upper:]' '[:lower:]' | sed 's/,/|/g')

# Log the selected options
echo "Listing ${workflow:-all} workflows older than ${older} days with status ${status}" >&2

gh run list --limit 500 ${workflow:+--workflow $workflow} --jq " .[]| select(.conclusion| test(\"$status\"))|
select(.createdAt < (now-( $older * 86400) | strftime(\"%Y-%m-%dT%H-%M-%SZ\") )) |
.databaseId" --json conclusion,databaseId,createdAt -R $repo
41 changes: 41 additions & 0 deletions actions/create-or-replace-ref/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# @format

name: 'Create or Replace Ref'
description: 'Creates a git ref (tag/branch). If it already exists, updates it to the given SHA.'
branding:
icon: 'tag'
color: 'blue'
inputs:
ref:
description: 'Full ref name (e.g. refs/tags/deploy/myhost)'
required: true
sha:
description: 'The SHA to point the ref at'
required: true
token:
description: 'GitHub token with contents write permission'
required: false
default: ${{ github.token }}
runs:
using: composite
steps:
- name: Create or Replace Ref
uses: actions/github-script@v8
with:
github-token: ${{ inputs.token }}
script: |
const { owner, repo } = context.repo;
const ref = '${{ inputs.ref }}';
const sha = '${{ inputs.sha }}';


try {
await github.rest.git.createRef({ owner, repo, ref, sha });
core.info(`Created ref ${ref} → ${sha}`);
} catch (err) {
if (err.status !== 422) throw err;
// 422 = ref already exists; force-update it
const shortRef = ref.replace(/^refs\//, '');
await github.rest.git.updateRef({ owner, repo, ref: shortRef, sha, force: true });
core.info(`Updated ref ${ref} → ${sha}`);
}
73 changes: 73 additions & 0 deletions actions/deploy/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# @format

name: 'Deploy PHP Project'
description: 'Deploy a PHP project using Deployer'
branding:
icon: 'check'
color: 'blue'
inputs:
php-version:
description: 'PHP version to use'
required: false
default: '8.3'
app-version:
description: 'Full semantic version string'
required: false
default: ''
ssh-private-key:
description: 'SSH private key for deployment'
required: true
default: ''
known-hosts:
description: 'Known hosts for SSH'
required: true
default: ''
ssh-config:
description: 'SSH configuration'
required: false
default: ''
selector:
description: 'Selector for the deployment'
required: false
default: 'all'
environment:
description: 'Force deployment to a specific environment'
required: false
default: ''
gitversion-configFilePath:
description: 'Path to the GitVersion configuration file'
required: false
default: 'gitversion.yml'
default-user-mail:
description: 'Default user mail for db seeding'
required: false
default: ''
default-user-name:
description: 'Default user name db seeding'
required: false
default: ''
runs:
using: composite
steps:
# Run GitVersion to get the version number
- name: Run GitVersion
id: gitversion
uses: ./packages/perspikapps/klick-deploy/actions/run-gitversion
with:
configFilePath: ${{ inputs.gitversion-configFilePath }}

# Deploy the application to the development environment or force deployment
- name: Deploy Application
uses: ./packages/perspikapps/klick-deploy/actions/run-deployer
with:
dep: deploy
options:
--app-version=${{ inputs.app-version || steps.gitversion.outputs.SemVer }}
--default-user-mail=${{ inputs.default-user-mail }}
--default-user-name=${{ inputs.default-user-name }}
selector: ${{ inputs.selector || 'all' }}
environment: ${{ inputs.environment }}
ssh-private-key: ${{ inputs.ssh-private-key }}
known-hosts: ${{ inputs.known-hosts }}
ssh-config: ${{ inputs.ssh-config }} # ssh_config; optional

Loading