Using GitLab Pages to host composer repositories

./vendor/bin/satis build ./satis.json ./public

We start by creating a composer project.

$ composer init

Then we require satis,  a composer library that creates static files to represent a composer repository.

$ composer require composer/satis

Satis accepts a json configuration file with a list of packages.  These packages can be hosted in a git repository or elsewhere.

{
  "name": "My Repository",
  "homepage": "https://username.gitlab.io/composer-repository/",
  "repositories": [
    { "type": "vcs", "url": "https://gitlab.com/username/package-1" },
    { "type": "vcs", "url": "https://gitlab.com/username/package-2" }
  ],
  "require-all": true
}

The command to create the composer library files is:

$ ./vendor/bin/satis build ./satis.json ./public

This will read the satis.json configuration and output the files into public.

Hosting

GitLab gives us the option to host a set of pages for each repository.  We need to use a CI pipeline by creating a .gitlab-ci.yml file in order to do this.  The following file starts up a php docker image, installs the composer libraries based on our composer.lock, and runs the satis build command.  The results of the build command are placed in a public directory that will be shared with the pages step.  Pages takes the files in the public directory and makes them available as staticly hosted pages.

image: php:7.2.18

stages:
  - build
  - deploy

build:
  stage: build
  before_script:
    - apt-get update
    - apt-get -y install git unzip
    - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
    - composer install -n --prefer-dist
  script:
    - ./vendor/bin/satis build ./satis.json ./public
  artifacts:
    paths:
      - public
  only:
    - master

pages:
  stage: deploy
  script:
    - echo 'Nothing to do.'
  artifacts:
    paths:
      - public
  only:
    - master

One last file we should create is .gitignore:

/vendor

Now we can check the following files in to our project, and push to the master branch of our repository.

$ tree -a -I .git
.
├── composer.json
├── composer.lock
├── .gitignore
├── .gitlab-ci.yml
└── satis.json

0 directories, 5 files

Now when we want to use any of the packages hosted by our repository we just need to add our repository to our composer.json file:

{
    ...
    "repositories": [{
        "type": "composer",
        "url": "https://username.gitlab.io/composer-repository/"
    }]
    ...
}

and require our package:

$ composer require username/package