├── data
├── db
│ └── .gitkeep
├── packages
│ └── .gitkeep
└── logs
│ └── .gitkeep
├── .dockerignore
├── module
└── DeployAgent
│ ├── view
│ ├── agent
│ │ └── index.phtml
│ ├── layout
│ │ └── layout.phtml
│ └── error
│ │ ├── index.phtml
│ │ └── 404.phtml
│ ├── src
│ ├── Task
│ │ ├── Runner
│ │ │ ├── Exception.php
│ │ │ ├── TaskRunnerInterface.php
│ │ │ ├── Command.php
│ │ │ └── TaskRunnerManager.php
│ │ ├── TaskManagerFactory.php
│ │ └── TaskManager.php
│ ├── Source
│ │ └── SourceInterface.php
│ ├── Exception
│ │ └── FileSystemException.php
│ ├── Resource
│ │ ├── ResourceInterface.php
│ │ ├── Archive
│ │ │ ├── Extractor
│ │ │ │ ├── ExtractorInterface.php
│ │ │ │ ├── ValidationResult.php
│ │ │ │ ├── TarGzExtractor.php
│ │ │ │ └── ZipExtractor.php
│ │ │ └── Archive.php
│ │ ├── AbstractResource.php
│ │ ├── Http
│ │ │ └── Http.php
│ │ └── FileSystem
│ │ │ └── Directory.php
│ ├── Iterator
│ │ ├── IteratorAwareInterface.php
│ │ ├── WrappedFilterInterface.php
│ │ ├── RecursiveDirectoryAggregate.php
│ │ ├── CallbackFilter.php
│ │ └── FilterIteratorAwareTrait.php
│ ├── EntityRepositoryProviderInterface.php
│ ├── Destination
│ │ └── DestinationInterface.php
│ ├── EntityManagerAwareInterface.php
│ ├── Controller
│ │ ├── IndexController.php
│ │ ├── HookController.php
│ │ └── ApplicationController.php
│ ├── Transport
│ │ ├── TransportInterface.php
│ │ └── Transport.php
│ ├── Workspace
│ │ └── Workspace.php
│ ├── Provider
│ │ ├── ProviderInterface.php
│ │ ├── AbstractProvider.php
│ │ └── Continuousphp.php
│ ├── Application
│ │ ├── ApplicationInterface.php
│ │ ├── ApplicationManager.php
│ │ └── Application.php
│ ├── Log
│ │ └── Writer
│ │ │ ├── ConsoleFactory.php
│ │ │ └── Console.php
│ ├── Event
│ │ ├── EventBroadcasterTrait.php
│ │ └── DeployEvent.php
│ ├── EntityRepositoryProviderTrait.php
│ ├── EntityManagerInitializer.php
│ └── Agent
│ │ └── Agent.php
│ ├── Module.php
│ └── config
│ └── module.config.php
├── config
├── autoload
│ ├── .gitignore
│ ├── global.php
│ ├── db.global.php
│ ├── db.test.php.dist
│ ├── local.php.dist
│ └── agent.global.php
└── application.config.php
├── agent
├── public
├── favicon.ico
├── .htaccess
└── index.php
├── resources
└── img
│ └── continuousphp-setup.png
├── behat.yml
├── infra
└── docker
│ ├── entrypoint.sh
│ ├── vhost.conf
│ ├── docker-compose.yml
│ ├── .htaccess
│ └── Dockerfile
├── phpcs.xml
├── scripts
└── post-create-project
├── continuous.yml
├── .gitignore
├── features
├── create-continuousphp-application.feature
├── list-continuousphp-application.feature
├── deploy-continuousphp-application.feature
└── bootstrap
│ ├── CliContext.php
│ └── DeployAgentContext.php
├── composer.json
├── Vagrantfile
├── README.md
└── LICENSE
/data/db/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | .git
2 |
--------------------------------------------------------------------------------
/data/packages/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/data/logs/.gitkeep:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/module/DeployAgent/view/agent/index.phtml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/config/autoload/.gitignore:
--------------------------------------------------------------------------------
1 | local.php
2 | *.local.php
3 |
--------------------------------------------------------------------------------
/agent:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 |
2 |
3 | Continuous Deploy Agent Coding standard
4 |
5 | module/DeployAgent/src
6 |
--------------------------------------------------------------------------------
/infra/docker/vhost.conf:
--------------------------------------------------------------------------------
1 |
2 | DocumentRoot /var/app/public
3 |
4 | DirectoryIndex index.php
5 | AllowOverride All
6 | Require all granted
7 |
8 |
9 |
--------------------------------------------------------------------------------
/scripts/post-create-project:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 |
5 | [
6 | 'connection' =>
7 | [
8 | 'orm_default' =>
9 | [
10 | 'driverClass' => 'Doctrine\DBAL\Driver\PDOSqlite\Driver',
11 | 'params' =>
12 | [
13 | 'path'=> __DIR__ . '/../../data/db/agent.db',
14 | ]
15 | ]
16 | ]
17 | ],
18 | ];
19 |
--------------------------------------------------------------------------------
/config/autoload/db.test.php.dist:
--------------------------------------------------------------------------------
1 |
5 | [
6 | 'connection' =>
7 | [
8 | 'orm_default' =>
9 | [
10 | 'driverClass' => 'Doctrine\DBAL\Driver\PDOSqlite\Driver',
11 | 'params' =>
12 | [
13 | 'path'=> __DIR__ . '/../../data/db/test.db',
14 | ]
15 | ]
16 | ]
17 | ],
18 | ];
19 |
--------------------------------------------------------------------------------
/config/autoload/local.php.dist:
--------------------------------------------------------------------------------
1 |
17 | [
18 | 'display_exceptions' => true,
19 | ]
20 | ];
21 |
--------------------------------------------------------------------------------
/module/DeployAgent/src/Task/Runner/Exception.php:
--------------------------------------------------------------------------------
1 | array(
9 | 'BsbFlysystem',
10 | 'DoctrineModule',
11 | 'Continuous\\DeployAgent',
12 | 'DoctrineORMModule'
13 | ),
14 | 'module_listener_options' => array(
15 | 'module_paths' => array(
16 | './module',
17 | './vendor',
18 | ),
19 | 'config_glob_paths' => array(
20 | __DIR__ . '/../config/autoload/{,*.}{global,local,test}.php',
21 | ),
22 | 'config_cache_key' => 'application.config.cache',
23 | 'config_cache_enabled' => false,
24 | 'module_map_cache_key' => 'application.module.cache',
25 | 'module_map_cache_enabled' => false,
26 | 'cache_dir' => 'data/cache/',
27 | ),
28 | );
29 |
--------------------------------------------------------------------------------
/config/autoload/agent.global.php:
--------------------------------------------------------------------------------
1 |
10 | [
11 | 'adapters' =>
12 | [
13 | 'packages' =>
14 | [
15 | 'type' => 'local',
16 | 'options' =>
17 | [
18 | 'root' => './data/packages'
19 | ]
20 | ]
21 | ]
22 | ],
23 |
24 | 'agent' => [
25 | 'package_retention' => 2, // package retention per application
26 | 'package_storage_path' => './data/packages', // flysystem adapter key to store package history
27 | /* hexadecimal key to crypt/decrypt sensitive data */
28 | 'hash-key' => 'f01ee0962998007d40c7ce32bfec773028785cadfa0064a467662cb87171012c'
29 | ]
30 | ];
--------------------------------------------------------------------------------
/module/DeployAgent/src/Iterator/WrappedFilterInterface.php:
--------------------------------------------------------------------------------
1 | redirect()->toRoute('zf-apigility/ui');
29 | }
30 |
31 | return new ViewModel();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/module/DeployAgent/view/layout/layout.phtml:
--------------------------------------------------------------------------------
1 | doctype(); ?>
2 |
3 |
4 |
5 | headTitle('Continuous Deploy Agent');
7 | echo $this->headMeta()->appendName('viewport', 'width=device-width, initial-scale=1.0');
8 | echo $this->headLink(array('rel' => 'icon', 'type' => '/image/vnd.microsoft.icon', 'href' => $this->basePath('/favicon.ico')));
9 | ?>
10 |
11 |
12 |
13 | content; ?>
14 |
15 |
25 | inlineScript() ?>
26 |
27 |
28 |
--------------------------------------------------------------------------------
/features/create-continuousphp-application.feature:
--------------------------------------------------------------------------------
1 | @continuousphp
2 | Feature: Create an application provided by continuousphp to automate the deployment of a specific pipeline
3 |
4 | Scenario: Create an application using the CLI
5 | Given I am in the "." folder
6 | When I run "./agent add application --provider=continuousphp --token=b52f9c7faf680988f88391b35e5e488883442036 --repository-provider=git-hub --repository=fdewinnetest/deploy-agent --pipeline=refs/heads/master --name=deploy-agent-staging --path=/tmp/test/application"
7 | Then the exit code should be "0"
8 | And I should have the application
9 | | provider | continuousphp |
10 | | token | b52f9c7faf680988f88391b35e5e488883442036 |
11 | | repositoryProvider | git-hub |
12 | | repository | fdewinnetest/deploy-agent |
13 | | pipeline | refs/heads/master |
14 | | name | deploy-agent-staging |
15 | | path | /tmp/test/application |
--------------------------------------------------------------------------------
/module/DeployAgent/src/Resource/Archive/Extractor/ExtractorInterface.php:
--------------------------------------------------------------------------------
1 | iterator = $iterator;
37 | return $this;
38 | }
39 |
40 | /**
41 | * @return \ArrayIterator
42 | */
43 | public function getIterator()
44 | {
45 | return $this->iterator ?: new \ArrayIterator;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/features/list-continuousphp-application.feature:
--------------------------------------------------------------------------------
1 | @continuousphp
2 | Feature: List all configured application
3 |
4 | Scenario: List no application using the CLI
5 | Given I am in the "." folder
6 | When I run "./agent list applications"
7 | Then the exit code should be "0"
8 | And the output should contain:
9 | """
10 | No application found
11 | """
12 |
13 | @filesystem
14 | Scenario: List an existing application using the CLI
15 | Given I am in the "." folder
16 | And I have the application
17 | | provider | continuousphp |
18 | | token | b52f9c7faf680988f88391b35e5e488883442036 |
19 | | repositoryProvider | git-hub |
20 | | repository | fdewinnetest/deploy-agent |
21 | | pipeline | refs/heads/master |
22 | | name | deploy-agent-staging |
23 | | path | /tmp/test/application |
24 | When I run "./agent list applications"
25 | Then the exit code should be "0"
26 | And the output should contain:
27 | """
28 | deploy-agent-staging
29 | """
30 |
--------------------------------------------------------------------------------
/infra/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM php:7.0-apache
2 |
3 | # Set default system timezone
4 | RUN ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime
5 |
6 | # Install last update and php extension
7 | RUN apt-get update && apt-get install -y --no-install-recommends \
8 | vim \
9 | bzip2 \
10 | zip \
11 | unzip \
12 | libbz2-dev \
13 | libmcrypt-dev \
14 | libicu-dev \
15 | && docker-php-ext-configure mysqli \
16 | && docker-php-ext-install mysqli pdo_mysql bz2 mcrypt intl \
17 | && rm -rf /var/lib/apt/lists/*
18 |
19 | # Install composer
20 | RUN curl -sS https://getcomposer.org/installer | php \
21 | && mv composer.phar /usr/bin/composer
22 |
23 | # Enable Apache Rewrite module
24 | RUN a2enmod rewrite
25 |
26 | # Default Vhost for developement
27 | COPY infra/docker/vhost.conf /etc/apache2/sites-available/000-default.conf
28 |
29 | # Implement application
30 | WORKDIR /var/app
31 | COPY . /var/app/
32 |
33 | # htaccess specific to docker app
34 | COPY infra/docker/.htaccess public/
35 |
36 | # Update project
37 | RUN /usr/bin/composer install --no-dev \
38 | && ./scripts/post-create-project \
39 | && chown www-data:www-data -R .
40 |
41 | COPY infra/docker/entrypoint.sh /
42 |
43 | ENTRYPOINT ["/entrypoint.sh", "apache2-foreground"]
44 |
--------------------------------------------------------------------------------
/module/DeployAgent/src/Provider/ProviderInterface.php:
--------------------------------------------------------------------------------
1 | command;
30 | }
31 |
32 | /**
33 | * @param mixed $command
34 | * @return Command
35 | */
36 | public function setCommand($command)
37 | {
38 | $this->command = $command;
39 | return $this;
40 | }
41 |
42 | public function run()
43 | {
44 | passthru($this->getCommand(), $return);
45 | if ($return) {
46 | throw new Exception('The command exit with code ' . $return, Exception::BAD_EXIT_EXCEPTION);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/module/DeployAgent/src/Resource/AbstractResource.php:
--------------------------------------------------------------------------------
1 | filesystem;
39 | }
40 |
41 | /**
42 | * @param Filesystem $filesystem
43 | * @return AbstractResource
44 | */
45 | public function setFilesystem($filesystem)
46 | {
47 | $this->filesystem = $filesystem;
48 | return $this;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/module/DeployAgent/src/Application/ApplicationInterface.php:
--------------------------------------------------------------------------------
1 | =5.5.0",
24 | "ext-pdo_sqlite": "*",
25 | "zendframework/zendframework": "2.5.2",
26 | "doctrine/doctrine-orm-module": "~0.10",
27 | "reprovinci/doctrine-encrypt": "~3.0",
28 | "bushbaby/flysystem": "~1.0",
29 | "continuousphp/sdk": "~0.3"
30 | },
31 | "require-dev": {
32 | "phpunit/phpunit": "4.1.*",
33 | "mikey179/vfsStream": "1.3.*@dev",
34 | "squizlabs/php_codesniffer": "^2.3",
35 | "behat/behat": "^3.0"
36 | },
37 | "autoload": {
38 | "psr-4": {
39 | "Continuous\\DeployAgent\\": "module/DeployAgent/src"
40 | },
41 | "classmap": [
42 | "module/DeployAgent/Module.php"
43 | ]
44 | },
45 | "autoload-dev": {
46 | "psr-4": {
47 | "Continuous\\Features\\": "features/bootstrap/"
48 | }
49 | },
50 | "scripts": {
51 | "post-create-project-cmd": "scripts/post-create-project"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/module/DeployAgent/src/Log/Writer/ConsoleFactory.php:
--------------------------------------------------------------------------------
1 | options = $options;
30 | }
31 |
32 | /**
33 | * Create service
34 | *
35 | * @param ServiceLocatorInterface $pluginManager
36 | * @return mixed
37 | */
38 | public function createService(ServiceLocatorInterface $pluginManager)
39 | {
40 | $writer = new Console($this->options);
41 |
42 | $console = $pluginManager->getServiceLocator()->get('Console');
43 | if ($console instanceof \Zend\Console\Adapter\AdapterInterface) {
44 | $writer->setConsole($console);
45 | }
46 |
47 | return $writer;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/module/DeployAgent/src/Iterator/RecursiveDirectoryAggregate.php:
--------------------------------------------------------------------------------
1 | isDir()) {
33 | throw new \InvalidArgumentException('Expecting directory');
34 | }
35 | $this->iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(
36 | $file->getPathname(),
37 | \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS
38 | ));
39 | }
40 |
41 | /**
42 | * @return \Iterator|\RecursiveIteratorIterator
43 | */
44 | public function getIterator()
45 | {
46 | return $this->iterator;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/module/DeployAgent/src/Iterator/CallbackFilter.php:
--------------------------------------------------------------------------------
1 | callback = $callable;
38 | }
39 |
40 | /**
41 | * @param \Iterator $iterator
42 | * @return mixed
43 | */
44 | public function getFilterIterator(\Iterator $iterator)
45 | {
46 | $filter = $this->iteratorClass;
47 | return new $filter($iterator, $this->callback);
48 | }
49 |
50 | /**
51 | * @return string
52 | */
53 | public function getIteratorName()
54 | {
55 | return $this->iteratorClass;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/module/DeployAgent/src/Resource/Archive/Extractor/ValidationResult.php:
--------------------------------------------------------------------------------
1 | valid = (bool) $valid;
33 |
34 | return $this;
35 | }
36 |
37 | /**
38 | * @param string $message
39 | *
40 | * @return self
41 | */
42 | public function setMessage($message)
43 | {
44 | $this->message = (string) $message;
45 | $this->valid = false;
46 |
47 | return $this;
48 | }
49 |
50 | /**
51 | * @return boolean
52 | */
53 | public function isValid()
54 | {
55 | return $this->valid;
56 | }
57 |
58 | /**
59 | * @return string
60 | */
61 | public function getMessage()
62 | {
63 | return $this->message;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Vagrantfile:
--------------------------------------------------------------------------------
1 | # -*- mode: ruby -*-
2 | # vi: set ft=ruby :
3 |
4 | VAGRANTFILE_API_VERSION = '2'
5 |
6 | @script = <