master 3d32c7d654bd cached
21 files
75.3 KB
19.1k tokens
15 symbols
1 requests
Download .txt
Repository: davidalger/capistrano-magento2
Branch: master
Commit: 3d32c7d654bd
Files: 21
Total size: 75.3 KB

Directory structure:
gitextract_nxtp9u_o/

├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── Gemfile
├── LICENSE.md
├── README.md
├── Rakefile
├── capistrano-magento2.gemspec
└── lib/
    ├── capistrano/
    │   ├── magento2/
    │   │   ├── cachetool.rb
    │   │   ├── defaults.rb
    │   │   ├── deploy.rb
    │   │   ├── notifier.rb
    │   │   ├── pending.rb
    │   │   └── version.rb
    │   ├── magento2.rb
    │   └── tasks/
    │       ├── cachetool.rake
    │       ├── deploy.rake
    │       ├── magento.rake
    │       ├── notifier.rake
    │       └── pending.rake
    └── capistrano-magento2.rb

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
/.bundle/
/.yardoc
/Gemfile.lock
/_yardoc/
/coverage/
/doc/
/pkg/
/spec/reports/
/tmp/


================================================
FILE: .travis.yml
================================================
language: ruby
rvm:
  2.4

before_install:
  - gem update --system
  - gem install bundler


================================================
FILE: CHANGELOG.md
================================================
# Capistrano::Magento2 Change Log

0.9.4
=========

* Updated to now set SELinux context on `var` directory with default type of `httpd_sys_rw_content_t` to allow application writes where SELinux is enabled.

0.9.3
=========

* Updated to now specify `--non-interactive` flag on `app:config:import` so CLI command will not hang trying for user input.

0.9.2
=========

* Fixed issue preventing use of `after` tasks on `magento:cache:flush` from being used to trigger service reloads at end of deployment ([issue #143](https://github.com/davidalger/capistrano-magento2/issues/143))
* Updated to use DSL method `invoke!` to call iterant tasks ([see capistrano/capistrano/pull/1911](https://github.com/capistrano/capistrano/pull/1911)))

0.9.1
=========

* Fixed regression in 0.9.0 where relying on the `-l` flag broke multilingual static content deployment ([issue #141](https://github.com/davidalger/capistrano-magento2/issues/141))

0.9.0
=========

**Upgrade Notes:**

As of this release only Magento 2.3 and later are supported and **support has been dropped for prior versions** which have long since reached their end-of-life. Moving forward versions past their EOL will no longer be supported by subsequent releases of this gem. Older versions of this gem may continue to be used to deploy older and EOL versions.

If using a `Gemfile` with Bundler to lock versions of dependencies used for execution, the version lock on `capistrano` should be updated to `~>1.13` to match the minimal requirement of this release, otherwise `bundle update` will fail to update to version `0.9.0` of this gem. The following is recommended:

```
gem 'capistrano', '~> 3.14'
gem 'capistrano-magento2', '~> 0.9'
```

If a capistrano version lock is present in a projects `deploy.rb` it will also need to be updated:

```
lock '~> 3.14'
```

**Change Summary:**

* Dropped support for EOL versions of Magento and scrubbed all gated logic around legacy behaviors in 2.1.x and 2.2.x
* Removed `magento:deploy:version_check` task and associated warning when attempting to deploy unsupported versions of Magento
* Updated required version of `capistrano` to `~> 1.13` (>=1.13 and less than 2.0)
* Resolved inability to use `--dry-run` flag ([issue #128](https://github.com/davidalger/capistrano-magento2/issues/128)) as made possible by the removal of all version related gating logic.
* Dropped explicit default of `:magento_deploy_languages`; will now only be passed to `bin/magento` call when set in project configuration.
* Updated zero-down deployment logic to rely on `app:config:status` to detect config changes rather than the md5sum of config.php in current and release directories.
* Added `magento:app:config:status` to available commands for manual execution.
* Fixes issue in 2.3.4 and later where app:config:import may fail if cache:flush is not run immediately prior ([issue #138](https://github.com/davidalger/capistrano-magento2/issues/138))

0.8.9
=========

* Fixed issue with RabbitMQ settings caused by app:config:import running after setup-upgrade step vs prior to the database upgrades (which connects to RabbitMQ in recurring data upgrade scripts)

0.8.8
==========

* Added support for zero-side-effect pipeline deployments when scopes/themes have been dumped to config.php

0.8.7
==========

* Updated use of `touch` to run such that SSHKit prefixes may be used (PR #110)

0.8.6
==========

* Fixed possible race condition in `magento:deploy:version_check` when `app/etc/env.php` resides on an NFS share

0.8.5
==========

* Added ability to override flags sent to `composer install` to workaround issue in Magento 2.3 beta preventing deploy

0.8.4
==========

* Disabled call to `magento:setup:db:schema:upgrade` when running a zero-down deployment
* Disabled call to `magento:setup:db:data:upgrade` when running a zero-down deployment
* Fixed possible race condition in `magento:deploy:mode:production` when `app/etc/env.php` resides on an NFS share

0.8.3
==========

* Fixed regression failing deployment when `:magento_deploy_composer` is set to `false` (PR #106)

0.8.2
==========

* Added `var/export` to default list of :linked_dirs to support bundled `dotmailer/dotmailer-magento2-extension` package

0.8.1
==========

* Added `require 'capistrano/magento2/cachetool'` which may be used to enable flushing the php-opcache when [cachetool](http://gordalina.github.io/cachetool/) is installed on the server
* Added `cachetool:opcache:status` and `cachetool:opcache:reset` commands (use `require 'capistrano/magento2/cachetool'` to enable them)
* Fixed issue causing deployment to disable maintenance mode when manually enabled prior to deployment (issue #16)

0.8.0
==========

* Added support for zero-down deployment (PR #104, issue #34)
* Added call to "composer dump-autoload --no-dev --optimize" following DI compliation (issue #102)

0.7.3
==========

* Optimized set permissions operation (PR #89)
* Fixed `uninitialized constant Capistrano::Magento2::Setup::DateTime` error (PR #93, issue #92)

0.7.2
==========

* Added support for Magento 2.2 [static content deploy strategies](http://bit.ly/2yhMvVv) (PR #85)
* Added support for Magento 2.2 [shared application config files](http://bit.ly/2gF8Ouu) (issue #83)

0.7.1
==========

* Fixed deploy routine so production mode is no longer enabled automatically when `:magento_deploy_production` is false
* Fixed regression in multi-lingual deployment (reverted boxing workaround with 2.1.7 upper limit; release notes are wrong and the issue persists in 2.1.8)
* Updated double run of static content deploy to only apply to versions prior to 2.1.8 (underling issue was resolved in 2.1.8)

0.7.0
==========

* Added support for Magento 2.2.0 release candidates
* Removed support for deployment of Magento versions older than 2.1.1
* Updated and optimized static content deployment for upcoming Magento 2.2.0 release
* Updated composer install routine; --no-dev is now used indiscriminately since Magento 2.1.1 and later support it; no more duplicate composer install commands (issue #76)
* Updated multi-lingual site deployment workaround to apply only to versions 2.1.3 through 2.1.7 as per 2.1.8 release notes the underlying issue has been resolved (issue #72)
* Added tasks to set production mode and show current mode (magento:deploy:mode:production and magento:deploy:mode:show)

0.6.6
==========

* Updated date formatting of pending change log output for enhanced readability (PR #73)
* Fixed bug in static content deploy resulting from a change in behaviour in Magento 2.1.3 and later (PR #74)

0.6.5
==========

* Added workaround for Magento 2.1.3 bug causing multi-lingual static-content deployment failure (issue #72)

0.6.4
==========

* Added support for the config.local.php file found in Magento 2.1.6 and later

0.6.3
==========

* Fixed deployment to multiple hosts resulting in disparate static content versions across target hosts

0.6.2
==========

* Added setting `:magento_deploy_jobs` to support configuring number of parallel static content deployment tasks
* Fixed issue where ./update dir may exist without a composer.json file, causing deployment failure
* Updated uses of bin/magento where output is parsed to include `--no-ansi` to eliminate potential failures
* Improved error reporting on static content deployment failure

0.6.1
==========

* Fixed Magento version check failing on some servers due to ansi output in non-interactive shells (issue #64)
* Added ability to configure Magento's composer authentication keys. See README for details (PR #56)
* Changed pending change log to hook into before `deploy:check` (previously hooked before `deploy`)

0.6.0
==========

* Added full-featured pending change logging functionality. See README for details (issue #58)
* Fixed inability to set PATH in capistrano configuration vs `.bashrc` file (issue #62)
* Updated README to reflect removing the `terminal-notifier` gem as a hard dependency (issue #19)
* Removed `capistrano-pending` as a dependency (issue #58)

0.5.9
==========

* Updated README with Capistrano 3.7 setup information
* Updated `linked_dirs` to link `pub/sitemaps` by default in similar fashion to the Magento1 deployment gem
* Updated README with guidance on adding a path to the list of `linked_dirs` without copying the entire configuration forward
* Fixed bug causing pipefail option to persist after `Capistrano::Magento2::Setup.static_content_deploy` is called
 
0.5.8
==========

* Fixed critical failure due to command map being broken in v0.5.7 updates (issue #50, issue #51)

0.5.7
==========
_Note: This release was yanked from RubyGems due to a critical failure in the deploy routine._

* Fixed failing deploys for Magento 2.1.0 caused by improper version checks on flags added in version 2.1.1 (issue #45)
* Fixed failure to detect error codes Magento 2.1.1 returns on a failed static-content deploy job (issue #44)

0.5.6
==========

* Fixed issue where setup:di:compile failing to return an exit code caused DI compilation failures to be masked (issue #41)

0.5.5
==========

* Fixed DI artifact mismatch caused by setup:ugprade overwriting frozen config.php post compilation
* Removed redundant (and non-functional) commands from deploy:reverted task
* Added informational output which lists the installed modules which are disabled per `app/etc/config.php`

0.5.4
==========

* Fixed issue causing failed releases when there are CSS compilation errors in setup:static-content:deploy task
* Updated static content deployment to ignore `:magento_deploy_themes` when deploying 2.0 and issue a warning message.

0.5.3
==========

* Added setting `:magento_deploy_cache_shared` for targeting cache related tasks (issue #33)
* Added setting `:magento_deploy_setup_role` for targeting setup related tasks (issue #33)
* Fixed magento setup, cache, index commands to only run on appropriate node(s) in multi-node deploys (issue #33).
* Fixed capistrano-pending support to play nicely with multiple hosts. Now only performs check on a single host.
* Updated `magento:deploy:verify` output with host specific messaging on configuration errors.

0.5.2
==========

* Added ability to configure permissions set on each deploy (issue #32). See README for details.

0.5.1
==========

* Fixed usability regression causing deploy confirmation to occur prior to display of `capistrano/magento2/pending` output when in use (issue #28)
* Fixed "REVISION file doesn't exist" error when deploying for the first time when `capistrano/magento2/pending` is loaded
* Fixed issue breaking initial deploy when `:magento_deploy_maintenance` is set to true

0.5.0
==========

* Added ability to only deploy specific themes via the new `:magento_deploy_themes` array
* Added `:magento_deploy_confim` setting which requires user confirmation of deployment to specific capistrano stages
* Added call to pre-generate secure RequireJS config (issue #21)
* Added workaround for Magento 2.1 specific bug where lack of a deployed_version.txt file would fail static asset deploy
* Added error check on output of setup:di:compile-multi-tenant since Magento 2.0 doesn't return error codes (issue #25)
* Updated formatting of pending deployment messaging
* Updated composer calls to specify --no-dev and --optimize-autoloader when `:magento_deploy_production` is not set (issue #22, #23)
* Fixed bug causing maintenance mode to be enabled on deploy even when `:magento_deploy_maintenance` was set to false
* Fixed bug preventing the second call to `magento:setup:permissions` from being executed (issue #18)
* Removed the undocumented `:deploy_warn_stages` setting from the notifier

0.4.0
==========

* Added optional support for capistrano-pending gem.
* Added `:magento_deploy_composer` flag. See README for details.
* Added `:magento_deploy_maintenance` flag. See README for details.
* Updated `:magento_deploy_languages` definition to explicitly declare default value.

0.3.0
==========

* Added `:magento_deploy_production` flag to disable production deploy commands (PR #10 by @giacmir).
* Added `:magento_deploy_languages` setting to support passing language list to static content generator (PR #11 by @giacmir).

0.2.4
==========

* Added internal `magento:deploy:check` task and `:linked_files_touch` setting to minimize manual server setup
* Moved default linked file for sitemap.xml into pub directory

0.2.3
==========

* Added file check to halt deploy if app/etc/config.php is not present in repository
* Added check to verify that app/etc/env.php contains an array with an install date

0.2.2
==========

* Revert "Add workaround for M2.0.4 bug noted in magento/magento2#4070"

0.2.1
==========

* Fixed issue with initial deploy failing before 'current' link has been created on target

0.2.0
==========

* Added "smart" magento:setup:di:compile task which uses multi-tenant if available (for compatibility with 2.0 release)
* Added a command_map for the bin/magento tool to simplify rake files
* Added indexer:info, indexer:status, indexer:show-mode, indexer:set-mode
* Added maintenance:status and maintenance:allow-ips, exposes maintenance:disable
* Fixed broken error detection logic on setup:static-content:deploy
* Fixed bug where magento:setup:upgrade was not using the --keep-generated flag
* Fixed log bloat caused by chatty static-content:deploy
* Fixed missing dependency include in deploy.rb
* Fixed output of magento:cache:varnish:ban command
* Fixed potential issue where if a botched release was in production, one could not roll back
* Fixed technical dependency bug preventing projects from overriding the deploy.rake with a custom one
* Renamed capistrano/magento2/deploy/notify to capistrano/magento2/notifier
* Renamed magento:reset_permissions to magento:setup:permissions
* Renamed magento:setup:static_content:deploy to magento:setup:static-content:deploy
* Updated composer calls to explicitly set  --prefer-dist and --no-interaction
* Updated README to reflect current setup instructions

0.1.3
==========

* Changed magento:cache:varnish:ban to use `:varnish_cache_hosts` array in deploy config vs hardcoding 127.0.0.1:6081

0.1.2
==========

* Added information to README file regarding use of terminal-notifier functionality

0.1.1
==========

* Initial functional release, tested with Magento 2.0.4 / PHP 7.0.5


================================================
FILE: Gemfile
================================================
##
 # Copyright © 2016 by David Alger. All rights reserved
 # 
 # Licensed under the Open Software License 3.0 (OSL-3.0)
 # See included LICENSE file for full text of OSL-3.0
 # 
 # http://davidalger.com/contact/
 ##

source 'https://rubygems.org'
gemspec


================================================
FILE: LICENSE.md
================================================
Open Software License v3.0 ("OSL")

This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work:

Licensed under the Open Software License version 3.0

1) Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following:

    a) to reproduce the Original Work in copies, either alone or as part of a collective work;

    b) to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work;

    c) to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License;

    d) to perform the Original Work publicly; and

    e) to display the Original Work publicly.

2) Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works.

3) Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work.

4) Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license.

5) External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c).

6) Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.

7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer.

8) Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation.

9) Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c).

10) Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.

11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License.

12) Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.

13) Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.

14) Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

15) Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.

16) Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process.

================================================
FILE: README.md
================================================
# Capistrano::Magento2

[![Gem Version](https://badge.fury.io/rb/capistrano-magento2.svg)](https://badge.fury.io/rb/capistrano-magento2)

A Capistrano extension for Magento 2 deployments. Takes care of specific Magento 2 requirements and adds tasks specific to the Magento 2 application. Supports zero-down deployments based on differences in deployed `config.php` and db status as reported by Magento's `setup:db:status` CLI command. When themes and scopes have been dumped to `config.php` via `bin/magento app:config:dump scopes themes i18n` then zero-side-effect pipeline will be utilized such that no database nor cache backend configuration are available during the build process.

## Supported Magento Versions

The following describes minimum Magento versions supported by releases of this gem. Please use an earlier version to deploy older releases of Magento not supported by the most recent iterations of this gem.

* Version 0.9.x supports deployment of Magento 2.3.0 and later.
* Version 0.7.x supports deployment of Magento 2.1.1 and later.

## Installation

### Standalone Installation

    $ gem install capistrano-magento2

### Using Bundler

1. Add the following to your project's `Gemfile`:

    ```ruby
    source 'https://rubygems.org'
    gem 'capistrano-magento2'
    ```

2. Execute the following:

        $ bundle install

## Usage

1. Install Capistrano in your Magento project:
    
    ```shell
    $ cd <project_root>
    $ mkdir -p tools/cap
    $ cd ./tools/cap
    $ cap install
    ```
_Note: By default, Capistrano creates "staging" and "production" stages. If you want to define custom staging areas, you can do so using the "STAGES" option (e.g. `cap install STAGES=stage,prod`). Built-in notifications ([see below](#terminal-notifier-on-os-x)) confirm deploy action on both "production" and "prod" area names by default._

2. Update your project's `Capfile` to look like the following:

    ```ruby
    # Load DSL and set up stages
    require 'capistrano/setup'
    
    # Load Magento deployment tasks
    require 'capistrano/magento2/deploy'
    require 'capistrano/magento2/pending'
    
    # Load Git plugin
    require "capistrano/scm/git"
    install_plugin Capistrano::SCM::Git
    
    # Load custom tasks from `lib/capistrano/tasks` if you have any defined
    Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
    ```

3. Configure Capistrano, per the [Capistrano Configuration](#capistrano-configuration) section below.

4. Configure your server(s), per the [Server Configuration](#server-configuration) section below.

5. Deploy Magento 2 to staging or production by running the following command in the `tools/cap` directory:
    
    ```shell
    $ cap staging deploy
    ```
    or
    ```shell
    $ cap production deploy
    ```
    
## Default Configuration

### Capistrano Configuration

Before you can use Capistrano to deploy, you must configure the `config/deploy.rb` and `config/deploy/*.rb` files. This section will cover the basic details for configuring these files. Refer to the [Capistrano documentation](http://capistranorb.com/documentation/getting-started/preparing-your-application/#configure-your-server-addresses-in-the-generated-files) and [README](https://github.com/capistrano/capistrano/blob/master/README.md) for more details.

1. Configuring `config/deploy.rb`
    
    Update the `:application` and `:repo_url` values in `config/deploy.rb`:
    
    ```ruby
    # Something unique such as the website or company name
    set :application, 'example'
    # The repository that hosts the Magento 2 application (Magento should live in the root of the repo)
    set :repo_url, 'git@github.com:acme/example-com.git'
    ```

2. Configuring `config/deploy/*.rb` files
    
    Capistrano allows you to use server-based or role-based syntax. You can read through the comments in the file to learn more about each option. If you have a single application server then the server-based syntax is the simplest configuration option.
    
    * Single application server
        
        If your stage and production environments consist of a single application server, your configuration files should look something like this:
        
        `config/deploy/production.rb`
        ```ruby
        server 'www.example.com', user: 'www-data', roles: %w{app db web}
        
        set :deploy_to, '/var/www/html'
        set :branch, proc { `git rev-parse --abbrev-ref master`.chomp }
        ```
        
        `config/deploy/staging.rb`
        ```ruby
        server 'stage.example.com', user: 'www-data', roles: %w{app db web}
        
        set :deploy_to, '/var/www/html'
        set :branch, proc { `git rev-parse --abbrev-ref develop`.chomp }
        ```
        
    * Multiple application servers
        
        Refer to the "role-based syntax" comments in the `config/deploy/*.rb` files or to the [Capistrano documentation](http://capistranorb.com/documentation/getting-started/preparing-your-application/#configure-your-server-addresses-in-the-generated-files) for details on how to configure multiple application servers.

### Magento Deploy Settings

| setting                        | default  | what it does
| ------------------------------ | -------- | ---
| `:magento_deploy_setup_role`   | `:all`   | Role from which primary host is chosen to run things like setup:upgrade on
| `:magento_deploy_cache_shared` | `true`   | If true, cache operations are restricted to the primary node in setup role
| `:magento_deploy_languages`    | `[]`     | Array of languages passed to static content deploy routine
| `:magento_deploy_themes`       | `[]`     | Array of themes passed to static content deploy
| `:magento_deploy_jobs`         | `nil`    | Number of threads to use for static content deploy
| `:magento_deploy_composer`     | `true`   | Enables composer install behavior in the built-in deploy routine
| `:magento_deploy_production`   | `true`   | Enables production specific DI compilation and static content generation
| `:magento_deploy_no_dev`       | `true`   | Enables use of --no-dev flag on composer install
| `:magento_deploy_maintenance`  | `true`   | Enables use of maintenance mode while magento:setup:upgrade runs
| `:magento_deploy_confirm`      | `[]`     | Used to require confirmation of deployment to a set of capistrano stages
| `:magento_deploy_chmod_d`      | `'2770'` | Default permissions applied to all directories in the release path
| `:magento_deploy_chmod_f`      | `'0660'` | Default permissions applied to all non-executable files in the release path
| `:magento_deploy_chmod_x`      | `['bin/magento']` | Default list of files in release path to set executable bit on
| `:magento_deploy_chcon_dirs`   | `['var']`         | Default list of directories on which to recursively set an SELinux context type
| `:magento_deploy_chcon_type`   | `httpd_sys_rw_content_t` | Default SELinux context type to set on directories which should be writeable by application
| `:magento_deploy_strategy`     | `nil`    | Can be `quick`, `standard` or `compact`

#### Example Usage

Add a line similar to the following in `config/deploy.rb` to set a custom value on one of the above settings:

```ruby
set :magento_deploy_jobs, '$(nproc)'
set :magento_deploy_themes, ['Magento/backend', 'Magento/blank']
set :magento_deploy_languages, ['en_US', 'en_CA']
```

### Capistrano Built-Ins

For the sake of simplicity in new project setups `:linked_dirs` and `:linked_files` are pre-configured per the following.

```ruby
set :linked_files, [
  'app/etc/env.php',
  'var/.setup_cronjob_status',
  'var/.update_cronjob_status'
]

set :linked_dirs, [
  'pub/media',
  'pub/sitemaps',
  'var/backups', 
  'var/composer_home', 
  'var/importexport', 
  'var/import_history', 
  'var/log',
  'var/session', 
  'var/tmp'
]
```

If you would like to customize the linked files or directories for your project, you can copy either one or both of the above arrays into the `config/deploy.rb` or `config/deploy/*.rb` files and tweak them to fit your project's needs. Alternatively, you can add a single linked dir (or file) using `append` like this:

```ruby
append :linked_dirs, 'path/to/link'
```

### Composer Auth Credentials

Magento 2's composer repository requires auth credentials to install. These can be set on target servers in a global composer `auth.json` file, the project's `composer.json` or by setting them in your deployment configuration using the following two settings:

```ruby
set :magento_auth_public_key, '<your_public_key_here>'
set :magento_auth_private_key, '<your_prviate_key_here>'
```

To obtain these credentials, reference the official documentation on DevDocs: [Get your authentication keys](http://devdocs.magento.com/guides/v2.0/install-gde/prereq/connect-auth.html)

**Caution:** When using these settings, the values will be logged to the `log/capistrano.log` file by SSHKit. They will not, however, be included in the general command output by default.

### Magento 2 Deploy Routine

A pre-built deploy routine is available out-of-the-box. This can be overriden on a per-project basis by including only the Magento 2 specific tasks and defining your own `deploy.rake` file under `lib/capistrano/tasks` in your projects Capistrano install location.

To see what process the built-in routine runs, take a look at the included rake file here: https://github.com/davidalger/capistrano-magento2/blob/master/lib/capistrano/tasks/deploy.rake

## Server Configuration

### Web Server Root Path

Before deploying with Capistrano, you must update each of your web servers to point to the `current` directory inside of the configured `:deploy_to` directory. For example: `/var/www/html/current/pub` Refer to the [Capistrano Structure](http://capistranorb.com/documentation/getting-started/structure/) to learn more about Capistrano's folder structure.

### PHP Opcache Reset

When doing atomic deployments with php-opcache installed on a server, the cache will reach a full state after which application performance will degrade as a result of the opcache not being able to do it's job. To work nicely with this, there is support included for automatically resetting the php-opcache after a release is published.

To use this, include `require 'capistrano/magento2/cachetool'` in your `Capfile` and make sure there is an `/etc/cachetool.yml` or `/var/www/html/.cachetool.yml` (assuming `:deploy_to` points at `/var/www/html`) file configured with contents like the following:

    adapter: fastcgi
    fastcgi: /var/run/php-fpm/www-data.sock
    temp_dir: /dev/shm/cachetool
    extensions: [ opcache ]

With this configuration in place, be sure cachetool ([available from here](http://gordalina.github.io/cachetool/)) has already been installed on the server and is available in `$PATH`.

Congratulations! You should now begin to see the pre-deployemnt opcache status information when running a deployment followed immediately be the `cachetool opcache:reset` command used to keep things humming nicely along.

## Magento Specific Tasks

All Magento 2 tasks used by the built-in `deploy.rake` file as well as some additional commands are implemented and exposed to the end-user for use directly via the cap tool. You can also see this list by running `cap -T` from your shell.

| cap command                           | what it does                                       |
| ------------------------------------- | -------------------------------------------------- |
| magento:cache:clean                   | Clean Magento cache by types                       |
| magento:cache:disable                 | Disable Magento cache                              |
| magento:cache:enable                  | Enable Magento cache                               |
| magento:cache:flush                   | Flush Magento cache storage                        |
| magento:cache:status                  | Check Magento cache enabled status                 |
| magento:cache:varnish:ban             | Add ban to Varnish for url(s)                      |
| magento:composer:install              | Run composer install                               |
| magento:deploy:mode:production        | Enables production mode                            |
| magento:deploy:mode:show              | Displays current application mode                  |
| magento:indexer:info                  | Shows allowed indexers                             |
| magento:indexer:reindex               | Reindex data by all indexers                       |
| magento:indexer:set-mode[mode,index]  | Sets mode of all indexers                          |
| magento:indexer:show-mode[index]      | Shows mode of all indexers                         |
| magento:indexer:status                | Shows status of all indexers                       |
| magento:maintenance:allow-ips[ip]     | Sets maintenance mode exempt IPs                   |
| magento:maintenance:disable           | Disable maintenance mode                           |
| magento:maintenance:enable            | Enable maintenance mode                            |
| magento:maintenance:status            | Displays maintenance mode status                   |
| magento:setup:di:compile              | Runs dependency injection compilation routine      |
| magento:setup:permissions             | Sets proper permissions on application             |
| magento:setup:static-content:deploy   | Deploys static view files                          |
| magento:setup:upgrade                 | Run the Magento upgrade process                    |

## Pending Changes Support

When the line `require 'capistrano/magento2/pending'` is included in your `Capfile` per the recommended configuration above, this gem will report changes pending deployment in an abbreviated git log style format. Here is an example:

```
00:00 deploy:pending:log
      01 git fetch origin
    ✔ 01 dalger@localhost 1.241s
    ✔ 01 dalger@localhost 1.259s
      Changes pending deployment on web1 (tags/2.1.2 -> 2.1):
      f511288 Thu Feb 23 12:19:20 2017 -0600 David Alger (HEAD -> 2.1, tag: 2.1.4, origin/2.1) Magento 2.1.4
      7fb219c Thu Feb 23 12:17:11 2017 -0600 David Alger (tag: 2.1.3) Magento 2.1.3
      570c9b3 Thu Feb 23 12:12:43 2017 -0600 David Alger Updated capistrano configuration
      No changes to deploy on web2 (from and to are the same: 2.1 -> 2.1)
```

When there are no changes due for deployment to any host, a warning requiring confirmation will be emitted by default:

```
No changes to deploy on web1 (from and to are the same: 2.1 -> 2.1)
No changes to deploy on web2 (from and to are the same: 2.1 -> 2.1)
Are you sure you want to continue? [y/n]
```

This confirmational warning can be disabled by including the following in your project's configuration:

```ruby
set :magento_deploy_pending_warn, false
```

### Pending Changes Configuration

| setting                          | what it does
| -------------------------------- | ----------
| `:magento_deploy_pending_role`   | Role to check for pending changes on; defaults to `:all`
| `:magento_deploy_pending_warn`   | Set this to `false` to disable confirmational warning on zero-change deployments
| `:magento_deploy_pending_format` | Can be used to set a custom change log format; refer to `defaults.rb` for example

### Pending Changes Tasks

| cap command                           | what it does                                       |
| ------------------------------------- | -------------------------------------------------- |
| deploy:pending                        | Displays a summary of commits pending deployment   |

Note: For more details including screenshots of what this functionality does, reference [this post](https://github.com/davidalger/capistrano-magento2/issues/58#issuecomment-282404477).

## Terminal Notifier on OS X

This gem includes an optional configuration file include which adds notification support via the [terminal-notifier](https://rubygems.org/gems/terminal-notifier) gem. To configure notifications, simply add the following line to your `Capfile`:

```ruby
require 'capistrano/magento2/notifier'
```

**Notice:** The `terminal-notifier` gem is currently macOS specific and thus can not be used on generic *nix environments. Because this gem has been known to cause ruby stability issues on certain non-macOS environments, it is not specified as a hard requirement in this gem's gemspec. When using this functionality, it is expected the gem either be already present on your working environment or be added to your project's `Gemfile`:

```ruby
gem 'terminal-notifier'
```

## Development

After checking out the repo, run `bundle install` to install dependencies. Make the necessary changes, then run `bundle exec rake install` to install a modified version of the gem on your local system.

To release a new version, update the version number in `capistrano/magento2/version.rb`, merge all changes to master, and then run `bundle exec rake release`. This will create a git tag for the version (the tag will apply to the current HEAD), push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).

_Note: Releasing a new version of the gem is only possible for those with maintainer access to the gem on rubygems.org._

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/davidalger/capistrano-magento2.

## License

This project is licensed under the Open Software License 3.0 (OSL-3.0). See included LICENSE file for full text of OSL-3.0.


================================================
FILE: Rakefile
================================================
##
 # Copyright © 2016 by David Alger. All rights reserved
 # 
 # Licensed under the Open Software License 3.0 (OSL-3.0)
 # See included LICENSE file for full text of OSL-3.0
 # 
 # http://davidalger.com/contact/
 ##

require 'bundler/gem_tasks'

task default: %w[test]

task :test do
  puts "TODO: Create real integration tests!"
end


================================================
FILE: capistrano-magento2.gemspec
================================================
##
 # Copyright © 2016 by David Alger. All rights reserved
 # 
 # Licensed under the Open Software License 3.0 (OSL-3.0)
 # See included LICENSE file for full text of OSL-3.0
 # 
 # http://davidalger.com/contact/
 ##

lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'capistrano/magento2/version'

Gem::Specification.new do |spec|
  spec.name          = 'capistrano-magento2'
  spec.version       = Capistrano::Magento2::VERSION
  spec.authors       = ['David Alger']
  spec.email         = ['davidmalger@gmail.com']

  spec.summary       = %q{A Capistrano extension for Magento 2 deployments.}
  spec.description   = %Q{#{spec.summary} Takes care of specific Magento 2 requirements and adds tasks specific to the Magento 2 application.}
  spec.homepage      = 'https://github.com/davidalger/capistrano-magento2'
  spec.license       = 'OSL-3.0'

  spec.files         = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
  spec.bindir        = 'bin'
  spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
  spec.require_paths = ['lib']

  spec.add_dependency 'capistrano', '~> 3.14'

  spec.add_development_dependency 'bundler', '~> 2.1'
  spec.add_development_dependency 'rake', '~> 13.0'
end


================================================
FILE: lib/capistrano/magento2/cachetool.rb
================================================
##
 # Copyright © 2018 by David Alger. All rights reserved
 # 
 # Licensed under the Open Software License 3.0 (OSL-3.0)
 # See included LICENSE file for full text of OSL-3.0
 # 
 # http://davidalger.com/contact/
 ##

require 'capistrano/deploy'

SSHKit.config.command_map[:cachetool] = "/usr/bin/env cachetool --"

load File.expand_path('../../tasks/cachetool.rake', __FILE__)


================================================
FILE: lib/capistrano/magento2/defaults.rb
================================================
##
 # Copyright © 2016 by David Alger. All rights reserved
 # 
 # Licensed under the Open Software License 3.0 (OSL-3.0)
 # See included LICENSE file for full text of OSL-3.0
 # 
 # http://davidalger.com/contact/
 ##

set :linked_files, fetch(:linked_files, []).push(
  'app/etc/env.php',
  'var/.setup_cronjob_status',
  'var/.update_cronjob_status'
)

set :linked_files_touch, fetch(:linked_files_touch, []).push(
  'app/etc/env.php',
  'var/.setup_cronjob_status',
  'var/.update_cronjob_status'
)

set :linked_dirs, fetch(:linked_dirs, []).push(
  'pub/media',
  'pub/sitemaps',
  'var/backups',
  'var/composer_home',
  'var/importexport',
  'var/import_history',
  'var/export',
  'var/log',
  'var/session', 
  'var/tmp'
)

# magento composer repository auth credentials
set :magento_auth_repo_name, fetch(:magento_auth_repo_name, 'http-basic.repo.magento.com')
set :magento_auth_public_key, fetch(:magento_auth_public_key, false)
set :magento_auth_private_key, fetch(:magento_auth_private_key, false)

# deploy permissions defaults
set :magento_deploy_chmod_d, fetch(:magento_deploy_chmod_d, '2770')
set :magento_deploy_chmod_f, fetch(:magento_deploy_chmod_f, '0660')
set :magento_deploy_chmod_x, fetch(:magento_deploy_chmod_x, ['bin/magento'])

# deploy selinux defaults
set :magento_deploy_chcon_dirs, fetch(:magento_deploy_chcon_dirs, ['var'])
set :magento_deploy_chcon_type, fetch(:magento_deploy_chcon_type, 'httpd_sys_rw_content_t')

# deploy configuration defaults
set :magento_deploy_composer, fetch(:magento_deploy_composer, true)
set :magento_deploy_confirm, fetch(:magento_deploy_confirm, [])
set :magento_deploy_languages, fetch(:magento_deploy_languages, [])
set :magento_deploy_maintenance, fetch(:magento_deploy_maintenance, true)
set :magento_deploy_production, fetch(:magento_deploy_production, true)
set :magento_deploy_no_dev, fetch(:magento_deploy_no_dev, true)
set :magento_deploy_themes, fetch(:magento_deploy_themes, [])
set :magento_deploy_jobs, fetch(:magento_deploy_jobs, nil)
set :magento_deploy_strategy, fetch(:magento_deploy_strategy, nil)

# deploy targetting defaults
set :magento_deploy_setup_role, fetch(:magento_deploy_setup_role, :all)
set :magento_deploy_cache_shared, fetch(:magento_deploy_cache_shared, true)

# pending deploy check defaults
set :magento_deploy_pending_role, fetch(:magento_deploy_pending_role, :all)
set :magento_deploy_pending_warn, fetch(:magento_deploy_pending_warn, true)
set :magento_deploy_pending_format, fetch(
  :magento_deploy_pending_format,
  '--pretty="format:%C(yellow)%h %Cblue%>(12)%ai %Cgreen%<(7)%aN%Cred%d %Creset%s"'
)

# internal flags
set :magento_internal_zero_down_flag, fetch(:magento_internal_zero_down_flag, false)


================================================
FILE: lib/capistrano/magento2/deploy.rb
================================================
##
 # Copyright © 2016 by David Alger. All rights reserved
 # 
 # Licensed under the Open Software License 3.0 (OSL-3.0)
 # See included LICENSE file for full text of OSL-3.0
 # 
 # http://davidalger.com/contact/
 ##

require 'capistrano/deploy'
require 'capistrano/magento2'

load File.expand_path('../../tasks/deploy.rake', __FILE__)


================================================
FILE: lib/capistrano/magento2/notifier.rb
================================================
##
 # Copyright © 2016 by David Alger. All rights reserved
 # 
 # Licensed under the Open Software License 3.0 (OSL-3.0)
 # See included LICENSE file for full text of OSL-3.0
 # 
 # http://davidalger.com/contact/
 ##

require 'capistrano/deploy'

load File.expand_path('../../tasks/notifier.rake', __FILE__)


================================================
FILE: lib/capistrano/magento2/pending.rb
================================================
##
 # Copyright © 2016 by David Alger. All rights reserved
 # 
 # Licensed under the Open Software License 3.0 (OSL-3.0)
 # See included LICENSE file for full text of OSL-3.0
 # 
 # http://davidalger.com/contact/
 ##

require 'capistrano/deploy'
require 'capistrano/magento2'

module Capistrano
  module Magento2
    module Pending
      def ensure_revision inform_user = false
        if test "[ -f #{current_path}/REVISION ]"
          yield
        else
          warn "\e[0;31mSkipping pending changes check on #{host} (no REVISION file found)\e[0m" if inform_user
          return false
        end
        return true
      end

      def from_rev
        within current_path do
          current_revision = capture(:cat, "REVISION")

          run_locally do
            return capture(:git, "name-rev --always --name-only #{current_revision}") # find symbolic name for ref
          end
        end
      end

      def to_rev
        run_locally do
          to = fetch(:branch)

          # get target branch upstream if there is one
          if test(:git, "rev-parse --abbrev-ref --symbolic-full-name #{to}@{u}")
            to = capture(:git, "rev-parse --abbrev-ref --symbolic-full-name #{to}@{u}")
          end

          # find symbolic name for revision
          to = capture(:git, "name-rev --always --name-only #{to}")
        end
      end
    end
  end
end

load File.expand_path('../../tasks/pending.rake', __FILE__)


================================================
FILE: lib/capistrano/magento2/version.rb
================================================
##
 # Copyright © 2016 by David Alger. All rights reserved
 # 
 # Licensed under the Open Software License 3.0 (OSL-3.0)
 # See included LICENSE file for full text of OSL-3.0
 # 
 # http://davidalger.com/contact/
 ##

module Capistrano
  module Magento2
    VERSION = '0.9.4'
  end
end


================================================
FILE: lib/capistrano/magento2.rb
================================================
##
 # Copyright © 2016 by David Alger. All rights reserved
 # 
 # Licensed under the Open Software License 3.0 (OSL-3.0)
 # See included LICENSE file for full text of OSL-3.0
 # 
 # http://davidalger.com/contact/
 ##

require 'date'

SSHKit.config.command_map[:magento] = "/usr/bin/env php -f bin/magento --"

module Capistrano
  module Magento2
    module Helpers
      def disabled_modules
        output = capture :magento, 'module:status --no-ansi'
        output = output.split("disabled modules:\n", 2)[1]

        if output == nil or output.strip == "None"
          return []
        end
        return output.split("\n")
      end

      def cache_hosts
        return fetch(:magento_deploy_cache_shared) ? (primary fetch :magento_deploy_setup_role) : (release_roles :all)
      end
    end

    module Setup
      def deployed_version
        # Generate a static content version string, but only if one has not already been set on a previous call
        if not fetch(:magento_static_deployed_version)
          set :magento_static_deployed_version, DateTime.now.strftime("%s")
          info "Static content version: #{fetch(:magento_static_deployed_version)}"
        end
        return fetch(:magento_static_deployed_version)
      end
    end
  end
end

load File.expand_path('../tasks/magento.rake', __FILE__)

namespace :load do
  task :defaults do
    load 'capistrano/magento2/defaults.rb'
  end
end


================================================
FILE: lib/capistrano/tasks/cachetool.rake
================================================
##
 # Copyright © 2018 by David Alger. All rights reserved
 # 
 # Licensed under the Open Software License 3.0 (OSL-3.0)
 # See included LICENSE file for full text of OSL-3.0
 # 
 # http://davidalger.com/contact/
 ##

after "deploy:published", "cachetool:opcache:status"
after "deploy:published", "cachetool:opcache:reset"

namespace :cachetool do
 namespace :opcache do
   desc "Resets the contents of the php-opcode cache"
   task :reset do
     on release_roles :all do
       within release_path do
         execute :cachetool, 'opcache:reset'
       end
     end
   end

   desc "Show information about the php-opcode cache"
   task :status do
     # Due to nature of the output, run this in sequence vs in parallel (the default) with shortest possible wait time
     on release_roles(:all), in: :sequence, wait: 1 do
       within release_path do
         execute :cachetool, 'opcache:status'
       end
     end
   end
 end
end


================================================
FILE: lib/capistrano/tasks/deploy.rake
================================================
##
 # Copyright © 2016 by David Alger. All rights reserved
 # 
 # Licensed under the Open Software License 3.0 (OSL-3.0)
 # See included LICENSE file for full text of OSL-3.0
 # 
 # http://davidalger.com/contact/
 ##

include Capistrano::Magento2::Helpers

namespace :deploy do
  before 'deploy:check:linked_files', 'magento:deploy:check'

  # If both 'scopes' and 'themes' are available in app/etc/config.php then the build should not require database or
  # cache backend configuration to deploy. Removing the link to app/etc/env.php in this case prevents any possible
  # side effects that may arise from the build running in parallel to the live production release (such as the cache
  # being randomly disabled during the composer install step of the build, something which has been observed). This
  # requires "bin/magento app:config:dump scopes themes i18n" be run to dump theme/store config and the result comitted to repository
  before 'deploy:symlink:linked_files', :detect_scd_config do
    on primary fetch(:magento_deploy_setup_role) do
      unless test %Q[#{SSHKit.config.command_map[:php]} -r '
            $cfg = include "#{release_path}/app/etc/config.php";
            exit((int)(isset($cfg["scopes"]) && isset($cfg["themes"])));
        ']
        info "Removing app/etc/env.php from :linked_dirs for zero-side-effect pipeline deployment."
        remove :linked_files, 'app/etc/env.php'
      end
    end
  end

  before :starting, :confirm_action do
    if fetch(:magento_deploy_confirm).include? fetch(:stage).to_s
      print "\e[0;31m      Are you sure you want to deploy to #{fetch(:stage).to_s}? [y/n] \e[0m"
      proceed = STDIN.gets[0..0] rescue nil
      exit unless proceed == 'y' || proceed == 'Y'
    end
  end

  # Links app/etc/env.php if previously dropped from :linked_dirs in :detect_scd_config
  task 'symlink:link_env_php' do
    on release_roles :all do
      # Normally this would be wrapped in a conditional, but during SCD and/or DI compile Magento frequently writes
      # to cache_types -> compiled_config resulting in an env.php file being present (albeit the wrong one)
      execute :ln, "-fsn #{shared_path}/app/etc/env.php #{release_path}/app/etc/env.php"
    end
  end

  task :updated do
    invoke 'magento:deploy:verify'
    invoke 'magento:composer:install' if fetch(:magento_deploy_composer)
    invoke 'magento:setup:permissions'
    invoke 'magento:setup:selinux'

    if fetch(:magento_deploy_production)
      invoke 'magento:setup:static-content:deploy'
      invoke 'magento:setup:di:compile'
      invoke 'magento:composer:dump-autoload' if fetch(:magento_deploy_composer)
    end

    invoke 'deploy:symlink:link_env_php'

    if fetch(:magento_deploy_production)
      invoke 'magento:deploy:mode:production'
    end

    invoke! 'magento:setup:permissions'
    invoke 'magento:maintenance:check'
    invoke 'magento:maintenance:enable' if fetch(:magento_deploy_maintenance)

    on release_roles :all do
      if test "[ -f #{current_path}/bin/magento ]"
        within current_path do
          execute :magento, 'maintenance:enable' if fetch(:magento_deploy_maintenance)
        end
      end
    end

    if not fetch(:magento_internal_zero_down_flag)
      on cache_hosts do
        within release_path do
          execute :magento, 'cache:flush'
        end
      end
      invoke 'magento:app:config:import'
      invoke 'magento:setup:db:schema:upgrade'
      invoke 'magento:setup:db:data:upgrade'
    end

    on primary fetch(:magento_deploy_setup_role) do
      within release_path do
        _disabled_modules = disabled_modules
        if _disabled_modules.count > 0
          info "\nThe following modules are disabled per app/etc/config.php:\n"
          _disabled_modules.each do |module_name|
            info '- ' + module_name
          end
        end
      end
    end
  end

  task :published do
    invoke 'magento:cache:flush'
    invoke 'magento:cache:varnish:ban'
    invoke 'magento:maintenance:disable' if fetch(:magento_deploy_maintenance)
  end
end


================================================
FILE: lib/capistrano/tasks/magento.rake
================================================
##
 # Copyright © 2016 by David Alger. All rights reserved
 # 
 # Licensed under the Open Software License 3.0 (OSL-3.0)
 # See included LICENSE file for full text of OSL-3.0
 # 
 # http://davidalger.com/contact/
 ##

include Capistrano::Magento2::Helpers
include Capistrano::Magento2::Setup

namespace :magento do

  namespace :app do
    namespace :config do
      desc 'Create dump of application config'
      task :dump do
        on primary fetch(:magento_deploy_setup_role) do
          within release_path do
            execute :magento, 'app:config:dump'
          end
        end
      end
      
      desc 'Import data from shared config files'
      task :import do
        on primary fetch(:magento_deploy_setup_role) do
          within release_path do
            execute :magento, 'app:config:import --no-interaction'
          end
        end
      end
      
      desc 'Checks if config propagation requires update'
      task :status do
        on primary fetch(:magento_deploy_setup_role) do
          within release_path do
            execute :magento, 'app:config:status'
          end
        end
      end
    end
  end

  namespace :cache do
    desc 'Flush Magento cache storage'
    task :flush do
      on cache_hosts do
        within release_path do
          execute :magento, 'cache:flush'
        end
      end
    end
    
    desc 'Clean Magento cache by types'
    task :clean do
      on cache_hosts do
        within release_path do
          execute :magento, 'cache:clean'
        end
      end
    end
    
    desc 'Enable Magento cache'
    task :enable do
      on cache_hosts do
        within release_path do
          execute :magento, 'cache:enable'
        end
      end
    end
    
    desc 'Disable Magento cache'
    task :disable do
      on cache_hosts do
        within release_path do
          execute :magento, 'cache:disable'
        end
      end
    end
    
    desc 'Check Magento cache enabled status'
    task :status do
      on cache_hosts do
        within release_path do
          execute :magento, 'cache:status'
        end
      end
    end
  
    namespace :varnish do
      # TODO: Document what the magento:cache:varnish:ban task is for and how to use it. See also magento/magento2#4106
      desc 'Add ban to Varnish for url(s)'
      task :ban do
        on primary fetch(:magento_deploy_setup_role) do
          # TODO: Document use of :ban_pools and :varnish_cache_hosts in project config file
          next unless any? :ban_pools
          next unless any? :varnish_cache_hosts
          
          within release_path do
            for pool in fetch(:ban_pools) do
              for cache_host in fetch(:varnish_cache_hosts) do
                execute :curl, %W{-s -H 'X-Pool: #{pool}' -X PURGE #{cache_host}}
              end
            end
          end
        end
      end
    end
  end
  
  namespace :composer do
    desc 'Run composer install'
    task :install => :auth_config do

      on release_roles :all do
        within release_path do
          composer_flags = '--prefer-dist --no-interaction'

          if fetch(:magento_deploy_no_dev)
            composer_flags += ' --no-dev'
          end

          if fetch(:magento_deploy_production)
            composer_flags += ' --optimize-autoloader'
          end

          execute :composer, "install #{composer_flags} 2>&1"

          if test "[ -f #{release_path}/update/composer.json ]"   # can't count on this, but emit warning if not present
            execute :composer, "install #{composer_flags} -d ./update 2>&1"
          else
            puts "\e[0;31m    Warning: ./update/composer.json does not exist in repository!\n\e[0m\n"
          end
        end
      end
    end

    desc 'Run composer dump-autoload'
    task 'dump-autoload' do

      on release_roles :all do
        within release_path do
          composer_flags = '--no-interaction'

          if fetch(:magento_deploy_no_dev)
            composer_flags += ' --no-dev'
          end

          if fetch(:magento_deploy_production)
            composer_flags += ' --optimize'
          end

          execute :composer, "dump-autoload #{composer_flags} 2>&1"
        end
      end
    end

    task :auth_config do
      on release_roles :all do
        within release_path do
          if fetch(:magento_auth_public_key) and fetch(:magento_auth_private_key)
            execute :composer, :config, '-q',
              fetch(:magento_auth_repo_name),
              fetch(:magento_auth_public_key),
              fetch(:magento_auth_private_key),
              verbosity: Logger::DEBUG
          end
        end
      end
    end
  end

  namespace :deploy do
    namespace :mode do
      desc "Enables production mode"
      task :production do
        on release_roles(:all), in: :sequence, wait: 1 do
          within release_path do
            execute :magento, "deploy:mode:set production --skip-compilation"
          end
        end
      end
      
      desc "Displays current application mode"
      task :show do
        on release_roles :all do
          within release_path do
            execute :magento, "deploy:mode:show"
          end
        end
      end
    end

    task :check do
      on release_roles :all do
        next unless any? :linked_files_touch
        on release_roles :all do |host|
          join_paths(shared_path, fetch(:linked_files_touch)).each do |file|
            unless test "[ -f #{file} ]"
              execute :touch, file
            end
          end
        end
      end
    end

    task :verify do
      is_err = false
      on release_roles :all do
        unless test "[ -f #{release_path}/app/etc/config.php ]"
          error "\e[0;31mThe repository is missing app/etc/config.php. Please install the application and retry!\e[0m"
          exit 1  # only need to check the repo once, so we immediately exit
        end

        # Checking app/etc/env.php in shared_path vs release_path to support the zero-side-effect
        # builds as implemented in the :detect_scd_config hook of deploy.rake
        unless test %Q[#{SSHKit.config.command_map[:php]} -r '
              $cfg = include "#{shared_path}/app/etc/env.php";
              exit((int)!isset($cfg["install"]["date"]));
          ']
          error "\e[0;31mError on #{host}:\e[0m No environment configuration could be found." +
                " Please configure app/etc/env.php and retry!"
          is_err = true
        end
      end
      exit 1 if is_err
    end
  end

  namespace :setup do
    desc 'Updates the module load sequence and upgrades database schemas and data fixtures'
    task :upgrade do
      on primary fetch(:magento_deploy_setup_role) do
        within release_path do
          warn "\e[0;31mWarning: Use of magento:setup:upgrade on production systems is discouraged." +
               " See https://github.com/davidalger/capistrano-magento2/issues/34 for details.\e[0m\n"

          execute :magento, 'setup:upgrade --keep-generated'
        end
      end
    end
    
    namespace :db do
      desc 'Checks if DB schema or data requires upgrade'
      task :status do
        on primary fetch(:magento_deploy_setup_role) do
          within release_path do
            execute :magento, 'setup:db:status'
          end
        end
      end
      
      task :upgrade do
        on primary fetch(:magento_deploy_setup_role) do
          within release_path do
            db_status = capture :magento, 'setup:db:status --no-ansi', verbosity: Logger::INFO
            
            if not db_status.to_s.include? 'All modules are up to date'
              execute :magento, 'setup:db-schema:upgrade'
              execute :magento, 'setup:db-data:upgrade'
            end
          end
        end
      end
      
      desc 'Upgrades data fixtures'
      task 'schema:upgrade' do
        on primary fetch(:magento_deploy_setup_role) do
          within release_path do
            execute :magento, 'setup:db-schema:upgrade'
          end
        end
      end
      
      desc 'Upgrades database schema'
      task 'data:upgrade' do
        on primary fetch(:magento_deploy_setup_role) do
          within release_path do
            execute :magento, 'setup:db-data:upgrade'
          end
        end
      end
    end
    
    desc 'Sets proper permissions on application'
    task :permissions do
      on release_roles :all do
        within release_path do
          execute :find, release_path, "-type d ! -perm #{fetch(:magento_deploy_chmod_d).to_i} -exec chmod #{fetch(:magento_deploy_chmod_d).to_i} {} +"
          execute :find, release_path, "-type f ! -perm #{fetch(:magento_deploy_chmod_f).to_i} -exec chmod #{fetch(:magento_deploy_chmod_f).to_i} {} +"
          
          fetch(:magento_deploy_chmod_x).each() do |file|
            execute :chmod, "+x #{release_path}/#{file}"
          end
        end
      end
    end
    
    desc 'Sets proper selinux context on directories which are written to by web processes'
    task :selinux do
      on release_roles :all do
        with path: '/usr/sbin:$PATH' do
          if test "selinuxenabled"
            within release_path do
              fetch(:magento_deploy_chcon_dirs).each() do |dir|
                execute :chcon, "-RP -t #{fetch(:magento_deploy_chcon_type)} #{release_path}/#{dir}"
              end
            end
          end
        end
      end
    end

    namespace :di do
      desc 'Runs dependency injection compilation routine'
      task :compile do
        on release_roles :all do
          within release_path do
            with mage_mode: :production do
              execute :magento, "setup:di:compile"
            end
          end
        end
      end
    end
    
    namespace 'static-content' do
      desc 'Deploys static view files'
      task :deploy do
        on release_roles :all do
          with mage_mode: :production do
            deploy_languages = fetch(:magento_deploy_languages)
            if deploy_languages.count() > 0
              deploy_languages = deploy_languages.join(' ').prepend(' ')
            else
              deploy_languages = nil
            end

            deploy_themes = fetch(:magento_deploy_themes)
            if deploy_themes.count() > 0
              deploy_themes = deploy_themes.join(' -t ').prepend(' -t ')
            else
              deploy_themes = nil
            end

            deploy_jobs = fetch(:magento_deploy_jobs)
            if deploy_jobs
              deploy_jobs = " --jobs #{deploy_jobs}"
            else
              deploy_jobs = nil
            end

            # Static content compilation strategies that can be one of the following:
            # quick (default), standard (like previous versions) or compact
            compilation_strategy = fetch(:magento_deploy_strategy)
            if compilation_strategy
              compilation_strategy =  " -s #{compilation_strategy}"
            end

            within release_path do
              execute :magento, "setup:static-content:deploy#{compilation_strategy}#{deploy_jobs}#{deploy_languages}#{deploy_themes}"
            end

            # Set the deployed_version of static content to ensure it matches across all hosts
            upload!(StringIO.new(deployed_version), "#{release_path}/pub/static/deployed_version.txt")
          end
        end
      end
    end
  end

  namespace :maintenance do
    desc 'Enable maintenance mode'
    task :enable do
      on release_roles :all do
        within release_path do
          execute :magento, 'maintenance:enable'
        end
      end
    end

    # Internal command used to check if maintenance mode is neeeded and disable when zero-down deploy is
    # possible or when maintenance mode was previously enabled on the deploy target
    task :check do
      on primary fetch(:magento_deploy_setup_role) do
        maintenance_enabled = nil
        disable_maintenance = false     # Do not disable maintenance mode in absence of positive release checks

        if test "[ -d #{current_path} ]"
          within current_path do
            # If maintenance mode is already enabled, enable maintenance mode on new release and disable management to
            # avoid disabling maintenance mode in the event it was manually enabled prior to deployment
            info "Checking maintenance status..."
            maintenance_status = capture :magento, 'maintenance:status', raise_on_non_zero_exit: false

            if maintenance_status.to_s.include? 'maintenance mode is active'
              info "Maintenance mode is currently active."
              maintenance_enabled = true
            else
              info "Maintenance mode is currently inactive."
              maintenance_enabled = false
            end
            info ""
          end
        end

        # If maintenance is currently active, enable it on the newly deployed release
        if maintenance_enabled
          info "Enabling maintenance mode on new release to match active status of current release."
          on release_roles :all do
            within release_path do
              execute :magento, 'maintenance:enable'
            end
          end
          info ""
        end

        within release_path do
          info "Checking database status..."
          # Check setup:db:status output and if out-of-date do not disable maintenance mode
          database_status = capture :magento, 'setup:db:status', raise_on_non_zero_exit: false
          database_uptodate = false

          if database_status.to_s.include? 'All modules are up to date'
            info "All modules are up to date."
            info ""
            database_uptodate = true
          else
            puts "      #{database_status.gsub("\n", "\n      ").sub(" Run 'setup:upgrade' to update your DB schema and data.", "")}"
          end

          # Check app:config:status output and if out-of-date do not disable maintenance mode
          info "Checking config status..."
          config_status = capture :magento, 'app:config:status', raise_on_non_zero_exit: false
          config_uptodate = false

          if config_status.to_s.include? 'Config files are up to date'
            info "Config files are up to date."
            config_uptodate = true
          else
            puts "      #{config_status.gsub("\n", "\n      ").sub(" Run app:config:import or setup:upgrade command to synchronize configuration.", "")}"
          end
          info ""

          # If both checks above reported up-to-date status checks disable maintenance mode
          if database_uptodate and config_uptodate
            disable_maintenance = true
          end

          if maintenance_enabled
            info "Disabling maintenance mode management..."
            info "Maintenance mode was already active prior to deploy."
            set :magento_deploy_maintenance, false
          elsif disable_maintenance
            info "Disabling maintenance mode management..."
            info "There are no database updates or config changes. This is a zero-down deployment."
            set :magento_internal_zero_down_flag, true # Set internal flag to stop db schema/data upgrades from running
            set :magento_deploy_maintenance, false     # Disable maintenance mode management since it is not neccessary
          else
            info "Maintenance mode usage will be enforced per :magento_deploy_maintenance (setting is #{fetch(:magento_deploy_maintenance).to_s})"
          end
        end
      end
    end

    desc 'Disable maintenance mode'
    task :disable do
      on release_roles :all do
        within release_path do
          execute :magento, 'maintenance:disable'
        end
      end
    end

    desc 'Displays maintenance mode status'
    task :status do
      on release_roles :all do
        within release_path do
          execute :magento, 'maintenance:status'
        end
      end
    end

    desc 'Sets maintenance mode exempt IPs'
    task 'allow-ips', :ip do |t, args|
      on release_roles :all do
        within release_path do
          execute :magento, 'maintenance:allow-ips', args[:ip]
        end
      end
    end
  end

  namespace :indexer do
    desc 'Reindex data by all indexers'
    task :reindex do
      on primary fetch(:magento_deploy_setup_role) do
        within release_path do
          execute :magento, 'indexer:reindex'
        end
      end
    end

    desc 'Shows allowed indexers'
    task :info do
      on primary fetch(:magento_deploy_setup_role) do
        within release_path do
          execute :magento, 'indexer:info'
        end
      end
    end

    desc 'Shows status of all indexers'
    task :status do
      on primary fetch(:magento_deploy_setup_role) do
        within release_path do
          execute :magento, 'indexer:status'
        end
      end
    end

    desc 'Shows mode of all indexers'
    task 'show-mode', :index do |t, args|
      on primary fetch(:magento_deploy_setup_role) do
        within release_path do
          execute :magento, 'indexer:show-mode', args[:index]
        end
      end
    end

    desc 'Sets mode of all indexers'
    task 'set-mode', :mode, :index do |t, args|
      on primary fetch(:magento_deploy_setup_role) do
        within release_path do
          execute :magento, 'indexer:set-mode', args[:mode], args[:index]
        end
      end
    end
  end
end


================================================
FILE: lib/capistrano/tasks/notifier.rake
================================================
##
 # Copyright © 2016 by David Alger. All rights reserved
 # 
 # Licensed under the Open Software License 3.0 (OSL-3.0)
 # See included LICENSE file for full text of OSL-3.0
 # 
 # http://davidalger.com/contact/
 ##

require 'terminal-notifier'

namespace :deploy do
  after 'deploy:failed', :notify_user_failure do
    run_locally do
      set :message, "ERROR in deploying " + fetch(:application).to_s + " to " + fetch(:stage).to_s
      TerminalNotifier.notify(fetch(:message), :title => 'Capistrano')
    end
  end

  after :finished, :notify_user do
    run_locally do
      set :message, "Finished deploying " + fetch(:application).to_s + " to " + fetch(:stage).to_s
      TerminalNotifier.notify(fetch(:message), :title => 'Capistrano')
    end
  end
end


================================================
FILE: lib/capistrano/tasks/pending.rake
================================================
##
 # Copyright © 2016 by David Alger. All rights reserved
 # 
 # Licensed under the Open Software License 3.0 (OSL-3.0)
 # See included LICENSE file for full text of OSL-3.0
 # 
 # http://davidalger.com/contact/
 ##

include Capistrano::Magento2::Pending

before 'deploy:check', 'deploy:pending:warn'

namespace :deploy do
  desc "Displays a summary of commits pending deployment"
  task :pending => 'deploy:pending:log'

  namespace :pending do
    task :warn => :log do
      if fetch(:magento_deploy_pending_warn)
        need_warning = true

        on roles fetch(:magento_deploy_pending_role) do |host|
          has_revision = ensure_revision do
            # if any host has a change in revision, do not warn user
            need_warning = false if from_rev != to_rev
          end

          # if a host does not have a revision, do not warn user
          need_warning = false if not has_revision
        end

        # if there is nothing to deploy on any host, prompt user for confirmation
        if need_warning
          print "      Are you sure you want to continue? [y/n] \e[0m"

          proceed = STDIN.gets[0..0] rescue nil
          exit unless proceed == 'y' || proceed == 'Y'
        end
      end
    end

    task :log do
      on roles fetch(:magento_deploy_pending_role) do |host|
        ensure_revision true do
          # update local repository to ensure accuracy of report
          run_locally do
            execute :git, :fetch, :origin
          end

          # fetch current revision and revision to be deployed
          from = from_rev
          to = to_rev

          # if there is nothing to deploy on this host, inform the user
          if from == to
            info "\e[0;31mNo changes to deploy on #{host} (from and to are the same: #{from} -> #{to})\e[0m"
          else
            run_locally do
              header = "\e[0;90mChanges pending deployment on #{host} (#{from} -> #{to}):\e[0m\n"

              # capture log of commits between current revision and revision for deploy
              output = capture :git, :log, "#{from}..#{to}", fetch(:magento_deploy_pending_format)

              # if we get no results, flip refs to look at reverse log in case of rollback deployments
              if output.to_s.strip.empty?
                output = capture :git, :log, "#{to}..#{from}", fetch(:magento_deploy_pending_format)
                if not output.to_s.strip.empty?
                  header += "\e[0;31mWarning: It appears you may be going backwards in time on #{host} with this deployment!\e[0m\n"
                end
              end

              # write pending changes log
              (header + output).each_line do |line|
                info line
              end
            end
          end
        end
      end
    end
  end
end


================================================
FILE: lib/capistrano-magento2.rb
================================================
Download .txt
gitextract_nxtp9u_o/

├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── Gemfile
├── LICENSE.md
├── README.md
├── Rakefile
├── capistrano-magento2.gemspec
└── lib/
    ├── capistrano/
    │   ├── magento2/
    │   │   ├── cachetool.rb
    │   │   ├── defaults.rb
    │   │   ├── deploy.rb
    │   │   ├── notifier.rb
    │   │   ├── pending.rb
    │   │   └── version.rb
    │   ├── magento2.rb
    │   └── tasks/
    │       ├── cachetool.rake
    │       ├── deploy.rake
    │       ├── magento.rake
    │       ├── notifier.rake
    │       └── pending.rake
    └── capistrano-magento2.rb
Download .txt
SYMBOL INDEX (15 symbols across 3 files)

FILE: lib/capistrano/magento2.rb
  type Capistrano (line 14) | module Capistrano
    type Magento2 (line 15) | module Magento2
      type Helpers (line 16) | module Helpers
        function disabled_modules (line 17) | def disabled_modules
        function cache_hosts (line 27) | def cache_hosts
      type Setup (line 32) | module Setup
        function deployed_version (line 33) | def deployed_version

FILE: lib/capistrano/magento2/pending.rb
  type Capistrano (line 13) | module Capistrano
    type Magento2 (line 14) | module Magento2
      type Pending (line 15) | module Pending
        function ensure_revision (line 16) | def ensure_revision inform_user = false
        function from_rev (line 26) | def from_rev
        function to_rev (line 36) | def to_rev

FILE: lib/capistrano/magento2/version.rb
  type Capistrano (line 10) | module Capistrano
    type Magento2 (line 11) | module Magento2
Condensed preview — 21 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (80K chars).
[
  {
    "path": ".gitignore",
    "chars": 87,
    "preview": "/.bundle/\n/.yardoc\n/Gemfile.lock\n/_yardoc/\n/coverage/\n/doc/\n/pkg/\n/spec/reports/\n/tmp/\n"
  },
  {
    "path": ".travis.yml",
    "chars": 91,
    "preview": "language: ruby\nrvm:\n  2.4\n\nbefore_install:\n  - gem update --system\n  - gem install bundler\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 14301,
    "preview": "# Capistrano::Magento2 Change Log\n\n0.9.4\n=========\n\n* Updated to now set SELinux context on `var` directory with default"
  },
  {
    "path": "Gemfile",
    "chars": 256,
    "preview": "##\n # Copyright © 2016 by David Alger. All rights reserved\n # \n # Licensed under the Open Software License 3.0 (OSL-3.0)"
  },
  {
    "path": "LICENSE.md",
    "chars": 10292,
    "preview": "Open Software License v3.0 (\"OSL\")\n\nThis Open Software License (the \"License\") applies to any original work of authorshi"
  },
  {
    "path": "README.md",
    "chars": 17564,
    "preview": "# Capistrano::Magento2\n\n[![Gem Version](https://badge.fury.io/rb/capistrano-magento2.svg)](https://badge.fury.io/rb/capi"
  },
  {
    "path": "Rakefile",
    "chars": 335,
    "preview": "##\n # Copyright © 2016 by David Alger. All rights reserved\n # \n # Licensed under the Open Software License 3.0 (OSL-3.0)"
  },
  {
    "path": "capistrano-magento2.gemspec",
    "chars": 1303,
    "preview": "##\n # Copyright © 2016 by David Alger. All rights reserved\n # \n # Licensed under the Open Software License 3.0 (OSL-3.0)"
  },
  {
    "path": "lib/capistrano/magento2/cachetool.rb",
    "chars": 378,
    "preview": "##\n # Copyright © 2018 by David Alger. All rights reserved\n # \n # Licensed under the Open Software License 3.0 (OSL-3.0)"
  },
  {
    "path": "lib/capistrano/magento2/defaults.rb",
    "chars": 2707,
    "preview": "##\n # Copyright © 2016 by David Alger. All rights reserved\n # \n # Licensed under the Open Software License 3.0 (OSL-3.0)"
  },
  {
    "path": "lib/capistrano/magento2/deploy.rb",
    "chars": 336,
    "preview": "##\n # Copyright © 2016 by David Alger. All rights reserved\n # \n # Licensed under the Open Software License 3.0 (OSL-3.0)"
  },
  {
    "path": "lib/capistrano/magento2/notifier.rb",
    "chars": 308,
    "preview": "##\n # Copyright © 2016 by David Alger. All rights reserved\n # \n # Licensed under the Open Software License 3.0 (OSL-3.0)"
  },
  {
    "path": "lib/capistrano/magento2/pending.rb",
    "chars": 1441,
    "preview": "##\n # Copyright © 2016 by David Alger. All rights reserved\n # \n # Licensed under the Open Software License 3.0 (OSL-3.0)"
  },
  {
    "path": "lib/capistrano/magento2/version.rb",
    "chars": 286,
    "preview": "##\n # Copyright © 2016 by David Alger. All rights reserved\n # \n # Licensed under the Open Software License 3.0 (OSL-3.0)"
  },
  {
    "path": "lib/capistrano/magento2.rb",
    "chars": 1418,
    "preview": "##\n # Copyright © 2016 by David Alger. All rights reserved\n # \n # Licensed under the Open Software License 3.0 (OSL-3.0)"
  },
  {
    "path": "lib/capistrano/tasks/cachetool.rake",
    "chars": 935,
    "preview": "##\n # Copyright © 2018 by David Alger. All rights reserved\n # \n # Licensed under the Open Software License 3.0 (OSL-3.0)"
  },
  {
    "path": "lib/capistrano/tasks/deploy.rake",
    "chars": 4051,
    "preview": "##\n # Copyright © 2016 by David Alger. All rights reserved\n # \n # Licensed under the Open Software License 3.0 (OSL-3.0)"
  },
  {
    "path": "lib/capistrano/tasks/magento.rake",
    "chars": 17436,
    "preview": "##\n # Copyright © 2016 by David Alger. All rights reserved\n # \n # Licensed under the Open Software License 3.0 (OSL-3.0)"
  },
  {
    "path": "lib/capistrano/tasks/notifier.rake",
    "chars": 763,
    "preview": "##\n # Copyright © 2016 by David Alger. All rights reserved\n # \n # Licensed under the Open Software License 3.0 (OSL-3.0)"
  },
  {
    "path": "lib/capistrano/tasks/pending.rake",
    "chars": 2811,
    "preview": "##\n # Copyright © 2016 by David Alger. All rights reserved\n # \n # Licensed under the Open Software License 3.0 (OSL-3.0)"
  },
  {
    "path": "lib/capistrano-magento2.rb",
    "chars": 0,
    "preview": ""
  }
]

About this extraction

This page contains the full source code of the davidalger/capistrano-magento2 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 21 files (75.3 KB), approximately 19.1k tokens, and a symbol index with 15 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!