Using TGMPA with GitLab’s CI artifacts

TLDR: set some headers, see below.

TGMPA

TGMPA is a WordPress plugin that helps you to manage your theme dependencies. Just imagine your users experience: instead of ask them to check a README doc that recommends installing various plugins (and no way of enforcing them to do so), this panel will show up everywhere they go:

A basic config would look like this:

add_action('tgmpa_register', function () {
// if the plugin is not hosted on WP, add * at the begining of the URL
$plugins = [
"simple-taxonomy-ordering" => "https://downloads.wordpress.org/plugin/simple-taxonomy-ordering.1.2.4.zip",
];

$required_plugins = [];

$config = [
'is_automatic' => true,
'dismissable' => false,
];

foreach ($plugins as $plugin_name => $plugin_url) {
$required_plugins[$plugin_name] = [
'name' => $plugin_name,
'slug' => $plugin_name,
'required' => true,
'force_activation' => true,
];

if (substr($plugin_url, 0, 1) == '*') { // just a trickery to allow specifying a ZIP url
$required_plugins[$plugin_name]['source'] = substr($plugin_url, 1);
} else {
$required_plugins[$plugin_name]['external_url'] = $plugin_url;
}
}

tgmpa($required_plugins, $config);
});

GitLab CI

On almost evey project, I’m using composer for various PHP deps, nodejs for various JS deps and a few Grunt or Gulp tasks. Obviously enough, I don’t want to keep in my repo a huuuge vendor or node_modules folder, so I gitignore these suckers. But… this means that my code is NOT ready to use.

One of the thing I really, really like on GitLab is that I can have a build process run everytime I push some code. Why this is helpful? Well, GitLab CI deals with all these issues and I have the package ready to download from this address (this is called an artifact and is the result of the CI build process):

https://gitlab.com/iamntz/my-plugin-name/-/jobs/artifacts/master/download?job=my_plugin_name

Do you notice the job param? Is the same as the YAML key below!

However, what is the problem? You can’t download this package dirrectly; you must do this either from their UI or via an arcane curl command, that sets a http header:

- 'curl -L --header "PRIVATE-TOKEN: XXYYZZ" "https://gitlab.com/iamntz/my-plugin-name/-/jobs/artifacts/master/download?job=my_plugin_name" -o "my-plugin-name.zip"'

You can create a private token on this page. Just create one that only have read_registry scope enabled and set to not expire. Since this token can represent a security issue, please consider creating a dumb user to whom you provide only a read access and add that user to your project (instead of using your token).

.gitlab-ci.yml

image: tetraweb/php:7.1

before_script:
- docker-php-ext-enable zip
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
- php composer-setup.php
- php -r "unlink('composer-setup.php');"
- php composer.phar install --no-dev -o --prefer-dist # <<< add more tasks below
- mkdir -p my-plugin-name
- rsync -av --exclude-from='deploy-exclude-files.txt' . my-plugin-name # <<< this is where you'll have all the files you need to be deployed

my_plugin_name: # <<< this key is important and can be anything
retry: 2
cache: # <<< this block is optional, but it will improve build time untracked: true key: ${CI_BUILD_REF_NAME} paths: - node_modules/ - vendor/ artifacts: name: "${CI_BUILD_NAME}_${CI_BUILD_REF_NAME}" untracked: false paths: - my-plugin-name/ script: - echo 'Deploying!' ``` _In case you wonder, `deploy-exclude-files.txt` is a file that contains all files and folder you want to be excluded from your final ZIP file. It has one file/folder name per line and that's all_ Once the build process is done, as long as you are authentificated to gitlab, you will be able to access it on `https://gitlab.com/iamntz/my-plugin-name/-/jobs/artifacts/master/download?job=my_plugin_name` url. --- #### Best of both worlds But a problem arise: how can you specify that build artifact URL in your tgmpa config? Well, that's easier than you'd expect: just set a header! If you're digging into TGMPA code, you'll notice that it uses `WP_Http` class to download external fiels. This means that... you can set some options! ```language-php add_filter('http_request_args', function ($r, $url) { if (preg_match('/gitlab.com\/iamntz/', $url)) { $r['headers']['PRIVATE-TOKEN'] = 'XXYYZZ'; } return $r; }, 10, 2); ``` After that, you modify your tgmpa config to look like this (notice the `*` before the URL!): ```language-php $plugins = [ "simple-taxonomy-ordering" =&gt; "https://downloads.wordpress.org/plugin/simple-taxonomy-ordering.1.2.4.zip",
"my_plugin_name" =&gt; "*https://gitlab.com/iamntz/my-plugin-name/-/jobs/artifacts/master/download?job=my_plugin_name"
];

Yup, is that simple!

However, you may want to pay some attention to the preg_match('/gitlab.com\/iamntz/', $url) pattern and be as specific as you can (e.g. it may conflicts with GitLab’s releases feature). Just play around a little. 😉

Publicat de

Ionuț Staicu

este frontend & WordPress developer, iar în timpul liber administrează DevForum.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *