While working on Ansible-powered deployment, I’ve came across the “connection parameters pattern”. E.g. here is a typical set of variables that define where an app can find MySQL DB and how to access it:

MYSQL_HOST: db.example.net

Passing around five variables might be somewhat awkward, so, one can pack all of these values into URI-like construct:

MYSQL_DSN: mysql://user1:secret@db.example.net:3306/app_db

Later then it can be decomposed into components, e.g. this is a possible template for file:

MYSQL_HOST={{ MYSQL_DSN | urlsplit(“hostname”) }}
MYSQL_PORT={{ MYSQL_DSN | urlsplit(“port”) }}
MYSQL_USER={{ MYSQL_DSN | urlsplit(“username”) }}
MYSQL_PASSWORD={{ MYSQL_DSN | urlsplit(“password) }}

In previous article I’ve described a way to define meaningful semantic icon identifiers to be used with . But that was done on the CSS level, which does not provide much support in terms of syntax/type checking, e.g. wrong icon identifier does not generate warnings or errors, it’s just a blank space in the running application.

Now I’m going to describe a solution which covers TypeScript level (and, by extension, Angular templates too — as long as your editor is aware of Angular Language Service). It does not invalidate CSS approach — they work best together.

So, if you use…

With built-in Auto DevOps enabled, GitLab tends to run a full pipeline whenever anything of the following happens:

  • pushing
  • branching
  • merging (even if “Fast-forward merge” is configured)
  • tagging

And that tireless building on every possible occasion consumes all kinds of resources: CPU, disk space, developers’ time.

I guess there are many ways to solve this problem, but I’ve come up with two so far.

First way: change the flow

One can make sure that certain events are meaningful in the context of one’s workflow. Here is an example:

  1. Start build and test jobs only when new commits are pushed to branches.
  2. Start deployment jobs…

This is rather specific case, but I couldn’t find solution online, so, here it is.

After installing (it was done via Ansible role cloudalchemy/prometheus, but that should not matter) to get some real-time info about my MySQL 5.7 server, I was not able to gather metrics beyond few items like and , with the latter always being zero. To be clear, exporter was running, it was accessible, but it was reporting MySQL server to be down.

I have encountered following error in system logs:

Sep 05 20:49:02 host mysqld_exporter[2411]: time="2020-09-05T20:49:02+03:00" level=error msg="Error pinging mysqld: Error 1045: Access denied…

Photo by Harpal Singh on Unsplash

What we have:

  • Angular Material project,
  • with one or more icon libraries included as dependencies,
  • maybe some custom icons and/or icon fonts added as assets,
  • and icons used like this:
<span class="material-icons">arrow_circle_down</span>
<mat-icon fontSet="fa" fontIcon="fa-trash”></mat-icon>
<mat-icon fontSet=“custom-iconfont”>R</mat-icon>
  • and if you pass icons around as parameters to your components, things can get ugly:
export interface MenuItem {
caption: string;
link: string;
fontSet?: string;
fontIcon?: string;
iconContent?: string;

What we want to have:

  • semantically meaningful and uniform way to refer to icons in our code,
  • using single string as an identifier, e.g. in template:
<mat-icon fontIcon="add-to-basket"></mat-icon>
  • or in TypeScript:
export interface…

Photo by Pankaj Patel on Unsplash

So, we have:

  1. GitLab server, up and running.
  2. GitLab runner, registered and ready for some action.
  3. Built-in Docker registry is configured.
  4. A project hosted on that GitLab server, with some custom that might look like this (minimal example just to show the context):
- build
stage: build
image: alpine:latest
- |
apk add openssl curl bash git ...
# some build commands follow

See that thing? It installs tools essential for your building process, but it takes time every time the job is executed. …

Going to talk about shells, yep. Photo by Sahra Peterson on Unsplash.

Bad title, but nice little trick: you can use configuration file to define rich shell commands to be executed on a remote host. And here is an example.

Imagine you have a remote host with MySQL server on it, and sometimes you need to go there and execute a statement or two. You could wind up some visual DB admin tool like or , but maybe it’s just some quick query like , and simple utility like would do just fine. …

Barely related photo by AK¥N Cakiner on Unsplash

See previous article for literals and variables. Disclaimer is also there.


  • If all parts of your expression resolve to boolean values or non-negative numbers, you can replace and with and :
// Long:
// Short:
  • String concatenation can be replaced with interpolation:
// Long:
// Short:
  • Works even better with more complex expressions as interpolation implies parenthesis:
// Long:
// Short:
  • Making comparisons strict saves a character:
// Long:
// Shorter:
  • And rearranging code (if possible) to change static comparison part to zero can make it even shorter:

Somewhat related photo by sydney Rae on Unsplash

Update: there are more things in part 2.

There is a game for programmers — code golf, and its particular implementation — code-golf.io. The goal is to write a shortest possible program to perform some task, and that can be done in a variety of programming languages.

I have spent some time playing this game, and accumulated a number of techniques that help making programs short, and I want to share these techniques.


  • I’m not particularly good at code-golf, and I’m pretty sure there are much more advanced things that make your code shorter. …

Unrelated but beautiful photo by Joanna Malinowska

The task: make a trait with some columns that you can reuse in entity classes. Basically it just works:

namespace App\Entity\Utils;

use Doctrine\ORM\Mapping as ORM;
trait MyTrait
* @var string
* @ORM\Column("some_field", type="string")
protected $someField;

public function setSomeField(string $someField): self
$this->someField = $someField;
return $this;

public function getSomeField(): string
return $this->someField;

And later in the entity class:

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
* @ORM\Entity
class MyEntity
use App\Entity\Utils\MyTrait;

But what if you need to have an index on your reused column? You can’t add it…

Alex Kunin

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store