Composer for
Corporate Use

Stephan Hochdörfer // 04.10.2014

About me


  • Stephan Hochdörfer
  • Head of Technology, bitExpert AG
    (Mannheim, Germany)
  • S.Hochdoerfer@bitExpert.de
  • @shochdoerfer

  • #PHP, #DevOps, #Automation



Our story: Diversity

Back in the days: Subversion

No fixed dependencies

How can Composer help?


Clear dependencies

Transitive dependencies?





Transitive dependencies?

Transitive dependencies?

Security issues?




Check composer.lock file


$ php security-checker.phar security:check ./composer.lock
Security Check Report
~~~~~~~~~~~~~~~~~~~~~

Checked file: composer.lock


  [OK]
  0 packages have known vulnerabilities

Check composer.lock file


$ curl -H "Accept: application/json" https://security.sensiolabs.org/check_lock -F lock=@./composer.lock
[]
					
				

Be aware of licensing issues

Tracking package licenses

$ composer.phar licenses
Name: customer/project
Version: 1.0.0
Licenses: proprietary
Dependencies:

  phpoffice/phpexcel         1.8.0    LGPL
  pimple/pimple              v1.1.1   MIT
  psr/log                    1.0.0    MIT
  silex/silex                v1.2.1   MIT
  symfony/debug              v2.5.4   MIT
  symfony/event-dispatcher   v2.5.4   MIT
  symfony/http-foundation    v2.5.4   MIT
  symfony/http-kernel        v2.5.4   MIT
  symfony/routing            v2.5.4   MIT

Perspective change

Small problem domains

Choose the "perfect" toolset

Build your own packages

Package design challenges


Composer Use-Cases

1. Simplify your project setup

Set-up a new project

$ composer.phar create-project symfony/framework-standard-edition 
  myproject
$ composer.phar create-project --repository-url=https://satis.loc 
  my/installer myproject

Custom project installer

{
    "name": "my/project-installer",
    "type": "project",
    "license": "MIT"
}
$ composer.phar create-project --repository-url=https://satis.loc 
  my/project-installer myproject

Speeds up your project setup

Customizing customers apps

Standardize package layout

2. Split app, maintain core lib

3. Custom package events

  • (pre|post)-install-cmd
  • (pre|post)-update-cmd
  • (pre|post)-status-cmd
  • (pre|post)-package-install
  • (pre|post)-package-update
  • (pre|post)-package-uninstall
  • (pre|post)-autoload-dump
  • ...

Create custom scripts

{
    "scripts": {
        "post-update-cmd": "My\\Composer\\PostUpdate::execute",
        "post-install-cmd": [
            "My\\Composer\\PostInstall::warmCache",
            "phpunit"
        ]
    }
}

Manage assets



Vagrant Cachier Plugin

$ vagrant plugin install vagrant-cachier
VAGRANTFILE_API_VERSION = "2"

Vagrant.require_version ">= 1.6.0"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

    if Vagrant.has_plugin?("vagrant-cachier")
       config.cache.scope = :box
       config.cache.enable :composer
    end

    config.vm.define "wheezy" do |wheezy|
        wheezy.vm.box = 'debian-wheezy-64'
    end
end

Private packages?

Hosting your packages





Satis is a ultra-lightweight, static
file-based version of packagist.

Installing Satis

$ composer.phar create-project composer/satis --stability=dev

Running Satis

{
    "name": "My own repo",
    "homepage": "http://satis.mydomain.loc",
    "repositories": [
        { "type": "vcs", "url": "http://git.mydomain.loc/repo1.git" },
        { "type": "vcs", "url": "http://git.mydomain.loc/repo2.git" }
    ],
    "require-all": true,
    "archive": {
        "directory": "dist",
        "format": "zip",
        "skip-dev": false
    }
}
$ php bin/satis build config.json web/
$ php bin/satis build config.json web/ mycompany/mypackage

Mirror packages

{
    "name": "My own repo",
    "homepage": "http://satis.mydomain.loc",
    "require-dependencies": true,
    "require-dev-dependencies": true,
    "repositories": [
        { "type": "vcs", "url": "https://github.com/silexphp/Silex.git" }
    ],
    "archive": {
        "directory": "dist",
        "format": "zip",
        "skip-dev": false
    }
}

Your Satis Repository

Using Satis

{
    "require": {
        "php": ">=5.5.0",
        "zendframework/zend-mail": "2.2.*@stable",
        "mycompany/mypackage": "2.4.*@stable"
    },
    "repositories": [{
            "type": "composer",
            "url": "http://satis.mydomain.loc/"
        }
    ]
}
$ composer.phar install

Access Control?

Credential handling

$ composer.phar install
Loading composer repositories with package information
    Authentication required (satis.mydomain.loc):
      Username: myuser
      Password:
Do you want to store credentials for satis.mydomain.loc in 
~/.composer/auth.json ? [Yn]

Credential handling

{
    "http-basic": {
        "satis.mydomain.loc": {
            "username": "myuser",
            "password": "mypassword"
        },
        "git.mydomain.loc": {
            "username": "mygituser",
            "password": "mypassword"
        },
        "svn.mydomain.loc": {
            "username": "mysvnuser",
            "password": "mypassword"
        }
    }
}

Toran Proxy

Toran Proxy Setup

$ wget https://toranproxy.com/releases/toran-proxy-v1.1.4.tgz
$ tar xvfz toran-proxy-v1.1.4.tgz
$ cp app/config/parameters.yml.dist app/config/parameters.yml
$ php app/console server:run --env=prod

Your Toran Proxy






Jenkins Node Config

Jenkins Node Environment

Jenkins Job Config

Push Config files to node

Validate composer.json

Installing dependencies

Running the build

Run satis build for package

Jenkins Satis Job Config

Define Job Parameters

Executing Satis

Notify users after build

Running the build

Result








Thank you!








Do not forget to rate the talk:
https://joind.in/11788