Last active
December 1, 2021 15:21
-
-
Save koehnlein/8db25464bf9597f8ed962a8bcf6f8a29 to your computer and use it in GitHub Desktop.
simple deployment based on TYPO3 Surf and Gitlab CI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
stages: | |
- deploy | |
# use caching | |
cache: | |
key: "$CI_BUILD_REF_NAME/$CI_BUILD_STAGE" | |
paths: | |
- .caches/ | |
variables: | |
COMPOSER_CACHE_DIR: "$CI_PROJECT_DIR/.caches/composer" | |
SURF_WORKSPACE: "$CI_PROJECT_DIR/.caches/surf_workspace" | |
image: t3easy/surf:node | |
before_script: | |
# | |
# SSH key for connection to remote server | |
# @see https://docs.gitlab.com/ee/ci/ssh_keys/README.html | |
# | |
# Install ssh-agent if not already installed, it is required by Docker. | |
# (change apt-get to yum if you use a CentOS-based image) | |
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' | |
# Run ssh-agent (inside the build environment) | |
- eval $(ssh-agent -s) | |
# Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store | |
- ssh-add <(echo "$SSH_PRIVATE_KEY") | |
# For Docker builds disable host key checking. Be aware that by adding that | |
# you are suspectible to man-in-the-middle attacks. | |
# WARNING: Use this only with the Docker executor, if you use it with shell | |
# you will overwrite your user's SSH config. | |
- mkdir -p ~/.ssh | |
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' | |
# In order to properly check the server's host key, assuming you created the | |
# SSH_SERVER_HOSTKEYS variable previously, uncomment the following two lines | |
# instead. | |
# - mkdir -p ~/.ssh | |
# - '[[ -f /.dockerenv ]] && echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts' | |
# set npm cache to a folder that can be cached from gitlab ci | |
- npm config set cache $CI_PROJECT_DIR/.caches/npm | |
staging: | |
stage: deploy | |
script: | |
- surf deploy | |
only: | |
- master | |
live: | |
stage: deploy | |
when: manual | |
script: | |
- surf deploy | |
only: | |
- master | |
variables: | |
SURF_CONTEXT: 'Production' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** @var \TYPO3\Surf\Domain\Model\Deployment $deployment */ | |
use TYPO3\Surf\Domain\Model\Node; | |
use TYPO3\Surf\Domain\Model\SimpleWorkflow; | |
$projectName = 'My TYPO3 Project'; | |
switch(getenv('SURF_CONTEXT')) { | |
case 'Production': | |
echo "Not defined yet!\n"; | |
die(1); | |
$deploymentPath = '/srv/www/vhosts.d/myproject-on-live-server'; | |
$deploymentHost = 'www.example.com'; | |
$deploymentUser = 'myproject'; | |
$repositoryBranch = 'master'; | |
$baseUrl = 'https://www.example.com'; | |
$context = 'Production'; | |
break; | |
// Staging | |
default: | |
$deploymentPath = '/srv/www/vhosts.d/myproject-on-staging-server'; | |
$deploymentHost = 'staging.example.com'; | |
$deploymentPort = 4242; | |
$deploymentUser = 'root'; | |
$repositoryBranch = 'master'; | |
$baseUrl = 'http://user:[email protected]'; | |
$context = 'Production/Staging'; | |
} | |
// Set this if you do not have a remote repository | |
$repositoryUrl = '[email protected]:group/myproject.git'; | |
// Set this if your composer command is not available in PATH | |
//$composerCommandPath = 'composer'; | |
// Set this, if on remote host the correct PHP binary is not available in PATH | |
//$deployment->setOption('phpBinaryPathAndFilename', '/usr/local/bin/php7-70STABLE-CLI'); | |
// No changes are required in the default case below this point. | |
$application = new \TYPO3\Surf\Application\TYPO3\CMS(); | |
$deployment->addApplication($application); | |
// Set default config values | |
if (!isset($repositoryUrl)) { | |
$repositoryUrl = 'file://' . dirname(__DIR__); | |
} | |
if (!isset($repositoryBranch)) { | |
$repositoryBranch = getenv('DEPLOY_BRANCH') ?: 'master'; | |
} | |
if (!isset($composerCommandPath)) { | |
$composerCommandPath = 'composer'; | |
} | |
$node = new Node($deploymentHost); | |
$node->setHostname($deploymentHost); | |
if(isset($deploymentUser)) { | |
$node->setOption('username', $deploymentUser); | |
} | |
if(isset($deploymentPort)) { | |
$node->setOption('port', $deploymentPort); | |
} | |
$application->addNode($node); | |
$application->setOption('projectName', $projectName); | |
$application->setOption('repositoryUrl', $repositoryUrl); | |
$application->setOption('branch', $repositoryBranch); | |
$application->setOption('webDirectory', 'htdocs'); | |
$application->setDeploymentPath($deploymentPath); | |
$application->setOption('keepReleases', 5); | |
$application->setOption('composerCommandPath', $composerCommandPath); | |
if($context) { | |
$application->setContext($context); | |
} else { | |
$application->setContext('Production'); | |
} | |
// clear opcache | |
$application->setOption('baseUrl', $baseUrl); | |
$application->setOption( | |
'rsyncExcludes', | |
[ | |
'.DS_Store', | |
'Thumbs.db', | |
'/composer.json', | |
'/composer.lock', | |
'/.data', | |
'/docker-*', | |
'/.editorconfig', | |
'/.git*', | |
'/Gulpfile.js', | |
'/package.json', | |
'/node_modules', | |
'/README*', | |
'/.surf', | |
'/htdocs/fileadmin', | |
'/htdocs/uploads', | |
] | |
); | |
// Make sure we build from a clean state | |
$application->setOption('TYPO3\\Surf\\Task\\Package\\GitTask[hardClean]', true); | |
$deployment->onInitialize(function() use ($deployment, $application) { | |
/** @var SimpleWorkflow $workflow */ | |
$workflow = $deployment->getWorkflow(); | |
// build files | |
$workflow->defineTask('Koehnlein\\Distribution\\DefinedTask\\BuildTask', 'TYPO3\\Surf\\Task\\LocalShellTask', array( | |
'command' => array( | |
"cd {workspacePath}", | |
"npm install", | |
"npm run-script build" | |
), | |
)); | |
$workflow->afterStage('package', 'Koehnlein\\Distribution\\DefinedTask\\BuildTask'); | |
/* | |
// index.php as symlink not working on some servers (e.g. jweiland.net) | |
$workflow->defineTask('Koehnlein\\Distribution\\DefinedTask\\CopyIndexPhp', 'TYPO3\\Surf\\Task\\ShellTask', array( | |
'command' => array( | |
"rm {releasePath}/htdocs/index.php", | |
"cp {releasePath}/vendor/typo3/cms/index.php {releasePath}/htdocs/index.php", | |
) | |
)); | |
$workflow->afterStage('transfer', 'Koehnlein\\Distribution\\DefinedTask\\CopyIndexPhp'); | |
*/ | |
// configuration files | |
$workflow->defineTask('Koehnlein\\Distribution\\DefinedTask\\SymlinkLocalConfigurationTask', 'TYPO3\\Surf\\Task\\Generic\\CreateSymlinksTask', [ | |
'symlinks' => [ | |
'htdocs/.htaccess' => '../../../shared/Data/.htaccess' | |
'htdocs/typo3conf/LocalConfiguration.php' => '../../../../shared/Data/typo3conf/LocalConfiguration.php', | |
] | |
]); | |
$workflow->addTask('Koehnlein\\Distribution\\DefinedTask\\SymlinkLocalConfigurationTask', 'update', $application); | |
// clear opcache, see https://stackoverflow.com/a/40760221/7358195 | |
$application->setOption( | |
'scriptBasePath', | |
$deployment->getWorkspacePath($application) . '/' . $application->getOption('webDirectory') | |
); | |
$workflow->addTask('TYPO3\\Surf\\Task\\Php\\WebOpcacheResetCreateScriptTask', 'package', $application); | |
$workflow->addTask('TYPO3\\Surf\\Task\\Php\\WebOpcacheResetExecuteTask', 'switch', $application); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
OK I've figured it out and it works like a charm! Thanks a lot for this kickstart.