Skip to content

Commit

Permalink
using regexp for pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
rgaudin committed Dec 22, 2020
1 parent 6d366cd commit ecb42a1
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- name: Install dependencies
run: python -m pip install -U pytest black
- name: Black
run: black -c compute_tags.py
run: black -c compute_tags.py build_push.py
- name: Tests
run: pytest tests.py

4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.pyc
__pycache__
*.zim
*.egg-info/
65 changes: 64 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,64 @@
# openzim-docker-action
# docker-publish-action

[![GitHub release](https://img.shields.io/github/release/openzim/docker-publish-action.svg)](https://github.com/openzim/docker-publish-action/releases/latest)
[![CI workflow](https://img.shields.io/github/workflow/status/openzim/docker-publish-action/CI?label=CI&logo=github)](https://github.com/openzim/docker-publish-action/actions?workflow=CI)

A Github Action to automatically build and publish Openzim's images to **Both Docker Hub and Github Container Regisry**.


## Requirements

On ghcr.io, as for Docker Hub, first part of image name is the *user* owning the image. The user or organization must have enabled *Improved container support* first. Users do that in Settings > Feature preview and Organizations in Settings > Packages.

⚠️ this action is tailored for Openzim's workflow only. Use at your own risk.

## Usage


```yaml
name: Docker

on:
push:
branches:
- master
tags:
- v*

jobs:
build-and-push:
name: Deploy Docker Image
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Build and push
uses: openzim/docker-publish-action@v1
with:
image-path: openzim/zimit
on-master: dev
tag-pattern: /^v*([0-9.]+)$/
latest-on-tag: true
restrict-to: openzim/zimit
hub-username: ${{ secrets.DOCKERHUB_USERNAME }}
hub-password: ${{ secrets.DOCKERHUB_PASSWORD }}
ghcr-username: ${{ secrets.GHCR_USERNAME }}
ghcr-token: ${{ secrets.GHCR_TOKEN }}

```

**Note**: th top-part `on` is just a filter on running that workflow. You can omit it but it's safer to not run it on refs that you know won't trigger anything. See [documentation](https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#on).

| Input | Usage |
| :--- | :--- |
| `image-path` | **Name of your image on the registry** (without the version part).<br />Ex.: `openzim/zimit` would refer to [this image](https://hub.docker.com/r/openzim/zimit).<br />The same name is pushed on **both registries**. |
| `context` | **Path in the repository to use as build context**<br />Relative to repository root. Defaults to `.`. Ex: `dnscache` or `workers/slave`. |
| `dockerfile` | **Path to the Dockerfile recipe, relative to context**<br />Defaults to `Dockerfile`. Use `../` syntax if dockerfile is outside context. |
| `on-master` | **Tag to apply for every commit on default branch**.<br />Omit it if you don't want to push an image for non-tagged commits.<br />Only applies to commits on your default branch (`master` or `main`) |
| `tag-pattern` | **Regular expression to match tags with**.<br />Only git tags matching this regexp will trigger a build+push to the corresponding docker tag.<br />If not specifying a group, whole git tag is used as is on docker. |
| `latest-on-tag` | **Whether to push to docker tag `:latest` on every matched tag** (see `tag-pattern`)<br />Value must be `true` or `false`. Defaults to `false`. |
| `restrict-to` | **Don't push if action is run for a different repository**<br />Specify as `{owner}/{repository}`. |
| `hub-username` and `hub-password` | **Docker Hub user credentials to push images with** |
| `ghcr-username` and `ghcr-token` | **Github user credentials to push images with**<br />Token is a [PAT](https://github.com/settings/tokens) with `repo, workflow, write:packages` permissions.|


⚠️ After your initial run creating your image, you need to manually **make it public** via Github's UI (see packages) if you intend to pull images without authenticating.
9 changes: 7 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
name: Openzim Docker Action
description: Build and publish Docker Images
name: Openzim Docker Publish Action
description: Build and publish Docker Images to both Docker Hub and ghcr.
author: openzim
branding:
icon: package
color: green

inputs:
image-path:
description: target image path on both registries (ex. 'openzim/dnscache')
Expand Down
14 changes: 12 additions & 2 deletions compute_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import re
import sys

perl_re = re.compile(r"^/(.+)/$")

if os.getenv("RESTRICT_TO") and os.getenv("GITHUB_REPOSITORY") != os.getenv(
"RESTRICT_TO"
):
Expand All @@ -22,10 +24,18 @@
ref = os.getenv("GITHUB_REF").split("/", 2)[-1]
is_tag = os.getenv("GITHUB_REF").startswith("refs/tags/")
if is_tag:
exp = os.getenv("TAG_PATTERN", "").replace("*", "(.+)")
exp = os.getenv("TAG_PATTERN", "")
# convert from perl syntax (/pattern/) to python one
if perl_re.match(exp):
exp = perl_re.match(exp).groups()[-1]
res = re.match(exp, ref)
if res:
version_tags.append(res.groups()[0])
if res.groups():
# we have a matching tag with a group, use the group part
version_tags.append(res.groups()[0])
else:
# we have a matching tag without a group, use git tag
version_tags.append(ref)

if os.getenv("LATEST_ON_TAG", "").lower() == "true":
version_tags.append("latest")
Expand Down
52 changes: 45 additions & 7 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def test_dnscache_main(github_env, repo_name):
repo_name="openzim/zimfarm",
image_path="openzim/dnscache",
on_master="latest",
tag_pattern="dnscache-v*",
tag_pattern="/^dnscache-v([0-9.]+)$/",
restrict_to="openzim/zimfarm",
is_on_main_branch=True,
)
Expand All @@ -90,7 +90,7 @@ def test_dnscache_tag(github_env, repo_name):
repo_name="openzim/zimfarm",
image_path="openzim/dnscache",
on_master="latest",
tag_pattern="dnscache-v*",
tag_pattern="/^dnscache-v([0-9.]+)$/",
restrict_to="openzim/zimfarm",
is_on_main_branch=True,
is_tag="dnscache-v1.1",
Expand All @@ -107,7 +107,7 @@ def test_dnscache_tag_and_latest(github_env, repo_name):
repo_name="openzim/zimfarm",
image_path="openzim/dnscache",
on_master="latest",
tag_pattern="dnscache-v*",
tag_pattern="/^dnscache-v([0-9.]+)$/",
restrict_to="openzim/zimfarm",
is_on_main_branch=True,
is_tag="dnscache-v1.1",
Expand All @@ -126,7 +126,7 @@ def test_restrict_to(github_env):
repo_name="rgaudin/test",
image_path="openzim/dnscache",
on_master="latest",
tag_pattern="dnscache-v*",
tag_pattern="/^dnscache-v([0-9.]+)$/",
restrict_to="openzim/zimfarm",
is_on_main_branch=True,
)
Expand All @@ -141,7 +141,7 @@ def test_not_is_on_main_branch(github_env, repo_name):
repo_name=repo_name,
image_path="owner/image",
on_master="latest",
tag_pattern="dnscache-v*",
tag_pattern="/^dnscache-v([0-9.]+)$/",
is_on_main_branch=False,
)
)
Expand Down Expand Up @@ -170,7 +170,7 @@ def test_zimit_main(github_env, repo_name):
repo_name="openzim/zimit",
image_path="openzim/zimit",
on_master="dev",
tag_pattern="v*",
tag_pattern="v([0-9.]+)",
restrict_to="openzim/zimit",
is_on_main_branch=True,
)
Expand All @@ -187,7 +187,7 @@ def test_zimit_tag(github_env, repo_name):
repo_name="openzim/zimit",
image_path="openzim/zimit",
on_master="dev",
tag_pattern="v*",
tag_pattern="v([0-9.]+)",
restrict_to="openzim/zimit",
is_on_main_branch=True,
is_tag="v1.1",
Expand All @@ -212,3 +212,41 @@ def test_no_tag_on_master(github_env, repo_name):
)
)
assert len(res) == 0


@pytest.mark.parametrize(
"tag_pattern, tag, expected",
[
# no group
("v.+", "v1", "v1"),
("v.+", "v1.1", "v1.1"),
# group
("v([0-9.]+)", "v1", "1"),
("v([0-9.]+)", "v1.1", "1.1"),
# caret for start
("^v([0-9.]+)", "v1", "1"),
("^v([0-9.]+)", "v1.1", "1.1"),
# dollar for end
("^v([0-9.]+)$", "v1", "1"),
("^v([0-9.]+)$", "v1.1", "1.1"),
# perl syntax
("/v([0-9.]+)/", "v1", "1"),
("/v([0-9.]+)/", "v1.1", "1.1"),
# perl with caret and dollar
("/^v([0-9.]+)$/", "v1", "1"),
("/^v([0-9.]+)$/", "v1.1", "1.1"),
],
)
def test_tag_patterns(github_env, repo_name, tag_pattern, tag, expected):
res = launch_and_retrieve(
**get_env(
github_env=github_env,
repo_name=repo_name,
image_path=repo_name,
tag_pattern=tag_pattern,
is_tag=tag,
)
)
assert len(res) == 2
assert f"{repo_name}:{expected}" in res
assert f"ghcr.io/{repo_name}:{expected}" in res

0 comments on commit ecb42a1

Please sign in to comment.