Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add {timestamp} and {timestamp_local} placeholders #114

Merged
merged 1 commit into from
Jun 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 75 additions & 60 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -343,73 +343,88 @@ in the configuration file for the corresponding CI system. A template string
is a filepath containing placeholders of the form ``{field}``, where the
available placeholders are:

=================== ==========================================================
Placeholder Definition
=================== ==========================================================
``{year}`` The four-digit year in which the build was started or the
release was published
``{month}`` The two-digit month in which the build was started or the
release was published
``{day}`` The two-digit day in which the build was started or the
release was published
``{hour}`` The two-digit hour at which the build was started or the
release was published
``{minute}`` The two-digit minute at which the build was started or the
release was published
``{second}`` The two-digit second at which the build was started or the
release was published
``{ci}`` The name of the CI system (``github``, ``travis``, or
``appveyor``)
``{type}`` The event type that triggered the build (``cron``,
``manual``, ``pr``, or ``push``), or ``release`` for
GitHub releases
``{type_id}`` Further information on the triggering event; for ``cron``
and ``manual``, this is a timestamp for the start of the
build; for ``pr``, this is the number of the associated
pull request, or ``UNK`` if it cannot be determined; for
``push``, this is the name of the branch to which the push
was made (or possibly the tag that was pushed, if using
Appveyor) [1]_
``{release_tag}`` *(``releases_path`` only)* The release tag
``{build_commit}`` The hash of the commit the build ran against or that was
tagged for the release. Note that, for PR builds on
Travis and Appveyor, this is the hash of an autogenerated
merge commit.
``{commit}`` The hash of the original commit that triggered the build
or that was tagged for the release. For pull request
builds, this is the head of the PR branch, or ``UNK`` if
it cannot be determined. For other builds (along with PR
builds on GitHub Actions), this is always the same as
``{build_commit}``.
``{number}`` The run number of the workflow run (GitHub) or the build
number (Travis and Appveyor) [1]_
``{status}`` The success status of the workflow run (GitHub) or job
(Travis and Appveyor); the exact strings used depend on
the CI system [1]_
``{common_status}`` The success status of the workflow run or job, normalized
into one of ``success``, ``failed``, ``errored``, or
``incomplete`` [1]_
``{wf_name}`` *(GitHub only)* The name of the workflow [1]_
``{wf_file}`` *(GitHub only)* The basename of the workflow file
(including the file extension) [1]_
``{run_id}`` *(GitHub only)* The unique ID of the workflow run [1]_
``{job}`` *(Travis and Appveyor only)* The number of the job,
without the build number prefix (Travis) or the job ID
string (Appveyor) [1]_
``{job_index}`` *(Travis and Appveyor only)* The index of the job in the
list returned by the API, starting from 1 [1]_
``{job_env}`` *(Appveyor only)* The environment variables specific to
the job [1]_
``{job_env_hash}`` *(Appveyor only)* The SHA1 hash of ``{job_env}`` [1]_
=================== ==========================================================
====================== =======================================================
Placeholder Definition
====================== =======================================================
``{year}`` The four-digit year in which the build was started or
the release was published
``{month}`` The two-digit month in which the build was started or
the release was published
``{day}`` The two-digit day in which the build was started or the
release was published
``{hour}`` The two-digit hour at which the build was started or
the release was published
``{minute}`` The two-digit minute at which the build was started or
the release was published
``{second}`` The two-digit second at which the build was started or
the release was published
``{timestamp}`` The date & time at which the build was started or the
release was published. This is a Python datetime_
value; it can be formatted with a `strftime()`_ format
string by writing ``{timestamp:FORMAT}``, e.g.,
``{timestamp:%Y-%b-%d}`` will produce a string of the
form "2021-Jun-14". If written as just
``{timestamp}``, the date & time will be formatted in
ISO 8601 format.
``{timestamp_local}`` The date & time at which the build was started or the
release was published, in the local system timezone.
This is formatted in the same way as ``{timestamp}``.
``{ci}`` The name of the CI system (``github``, ``travis``, or
``appveyor``)
``{type}`` The event type that triggered the build (``cron``,
``manual``, ``pr``, or ``push``), or ``release`` for
GitHub releases
``{type_id}`` Further information on the triggering event; for
``cron`` and ``manual``, this is a timestamp for the
start of the build; for ``pr``, this is the number of
the associated pull request, or ``UNK`` if it cannot be
determined; for ``push``, this is the name of the
branch to which the push was made (or possibly the tag
that was pushed, if using Appveyor) [1]_
``{build_commit}`` The hash of the commit the build ran against or that
was tagged for the release. Note that, for PR builds
on Travis and Appveyor, this is the hash of an
autogenerated merge commit.
``{commit}`` The hash of the original commit that triggered the
build or that was tagged for the release. For pull
request builds, this is the head of the PR branch, or
``UNK`` if it cannot be determined. For other builds
(along with PR builds on GitHub Actions), this is
always the same as ``{build_commit}``.
``{number}`` The run number of the workflow run (GitHub) or the
build number (Travis and Appveyor) [1]_
``{status}`` The success status of the workflow run (GitHub) or job
(Travis and Appveyor); the exact strings used depend on
the CI system [1]_
``{common_status}`` The success status of the workflow run or job,
normalized into one of ``success``, ``failed``,
``errored``, or ``incomplete`` [1]_
``{wf_name}`` *(GitHub only)* The name of the workflow [1]_
``{wf_file}`` *(GitHub only)* The basename of the workflow file
(including the file extension) [1]_
``{run_id}`` *(GitHub only)* The unique ID of the workflow run [1]_
``{job}`` *(Travis and Appveyor only)* The number of the job,
without the build number prefix (Travis) or the job ID
string (Appveyor) [1]_
``{job_index}`` *(Travis and Appveyor only)* The index of the job in
the list returned by the API, starting from 1 [1]_
``{job_env}`` *(Appveyor only)* The environment variables specific to
the job [1]_
``{job_env_hash}`` *(Appveyor only)* The SHA1 hash of ``{job_env}`` [1]_
====================== =======================================================

.. _datetime: https://docs.python.org/3/library/datetime.html#datetime-objects
.. _strftime(): https://docs.python.org/3/library/datetime.html
#strftime-and-strptime-format-codes

.. [1] These placeholders are only available for ``path`` and
``artifacts_path``, not ``releases_path``

A placeholder's value may be truncated to the first ``n`` characters by writing
``{placeholder[:n]}``, e.g., ``{commit[:7]}``.

All timestamps and timestamp components are in UTC.
All timestamps and timestamp components (other than ``{timestamp_local}``) are
in UTC.

Path templates may also contain custom placeholders defined in the top-level
``vars`` mapping of the configuration.
Expand Down
2 changes: 1 addition & 1 deletion src/tinuous/appveyor.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def from_job(
envvars=removeprefix(job["name"], "Environment: "),
)

def path_fields(self) -> Dict[str, str]:
def path_fields(self) -> Dict[str, Any]:
fields = super().path_fields()
fields.update(
{
Expand Down
4 changes: 3 additions & 1 deletion src/tinuous/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,12 @@ class Config:
# To allow APIClient:
arbitrary_types_allowed = True

def path_fields(self) -> Dict[str, str]:
def path_fields(self) -> Dict[str, Any]:
utc_date = self.created_at.astimezone(timezone.utc)
commit = "UNK" if self.commit is None else self.commit
return {
"timestamp": utc_date,
"timestamp_local": self.created_at.astimezone(),
"year": utc_date.strftime("%Y"),
"month": utc_date.strftime("%m"),
"day": utc_date.strftime("%d"),
Expand Down
6 changes: 3 additions & 3 deletions src/tinuous/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from pathlib import Path
from shutil import rmtree
import tempfile
from typing import Dict, Iterator, List, Tuple
from typing import Any, Dict, Iterator, List, Tuple
from zipfile import ZipFile

from github import Github
Expand Down Expand Up @@ -203,7 +203,7 @@ class GHAAsset(BuildAsset):
workflow_file: str
run_id: int

def path_fields(self) -> Dict[str, str]:
def path_fields(self) -> Dict[str, Any]:
fields = super().path_fields()
fields.update(
{
Expand Down Expand Up @@ -361,7 +361,7 @@ class Config:
# To allow APIClient:
arbitrary_types_allowed = True

def path_fields(self) -> Dict[str, str]:
def path_fields(self) -> Dict[str, Any]:
utc_date = self.published_at.astimezone(timezone.utc)
return {
"year": utc_date.strftime("%Y"),
Expand Down
2 changes: 1 addition & 1 deletion src/tinuous/travis.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def from_job(
index=index,
)

def path_fields(self) -> Dict[str, str]:
def path_fields(self) -> Dict[str, Any]:
fields = super().path_fields()
fields.update(
{
Expand Down
2 changes: 1 addition & 1 deletion src/tinuous/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def get_field(


def expand_template(
template_str: str, fields: Dict[str, str], vars: Dict[str, str]
template_str: str, fields: Dict[str, Any], vars: Dict[str, str]
) -> str:
return LazySlicingFormatter(vars).format(template_str, **fields)

Expand Down
12 changes: 12 additions & 0 deletions test/test_util.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import datetime, timezone
from types import SimpleNamespace
from typing import Any, Dict
import pytest
Expand Down Expand Up @@ -41,6 +42,17 @@ def test_expand_template_unused_bad() -> None:
)


def test_expand_template_datetime_format() -> None:
assert (
expand_template(
"{when:%Y-%b-%d}",
{"when": datetime(2021, 6, 14, 14, 44, 25, tzinfo=timezone.utc)},
{},
)
== "2021-Jun-14"
)


@pytest.mark.parametrize(
"s,sl",
[
Expand Down