-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
188 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
FROM python:3-slim AS builder | ||
ADD . /app | ||
WORKDIR /app | ||
|
||
# We are installing a dependency here directly into our app source dir | ||
RUN pip install --target=/app requests packaging | ||
|
||
# A distroless container image with Python and some basics like SSL certificates | ||
# https://github.com/GoogleContainerTools/distroless | ||
FROM gcr.io/distroless/python3-debian10 | ||
COPY --from=builder /app /app | ||
WORKDIR /app | ||
ENV PYTHONPATH /app | ||
CMD ["/app/main.py"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Github package 'latest' tag wrangler for containers | ||
## Usage | ||
|
||
Plug in the necessary inputs to determine if the container being built should be tagged 'latest; at the package level, for example `dbt-redshift:latest`. | ||
|
||
## Inputs | ||
| Input | Description | | ||
| - | - | | ||
| `package` | Name of the GH package to check against | | ||
| `new_version` | Semver of new container | | ||
| `gh_token` | GH token with package read scope| | ||
| `halt_on_missing` | Return non-zero exit code if requested package does not exist. (defaults to false)| | ||
|
||
|
||
## Outputs | ||
| Output | Description | | ||
| - | - | | ||
| `latest` | Wether or not the new container should be tagged 'latest'| | ||
| `minor_latest` | Wether or not the new container should be tagged major.minor.latest | | ||
|
||
## Example workflow | ||
```yaml | ||
name: Ship it! | ||
on: | ||
workflow_dispatch: | ||
inputs: | ||
package: | ||
description: The package to publish | ||
required: true | ||
version_number: | ||
description: The version number | ||
required: true | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Wrangle latest tag | ||
id: is_latest | ||
uses: ./.github/actions/latest-wrangler | ||
with: | ||
package: ${{ github.event.inputs.package }} | ||
new_version: ${{ github.event.inputs.new_version }} | ||
gh_token: ${{ secrets.GITHUB_TOKEN }} | ||
- name: Print the results | ||
run: | | ||
echo "Is it latest? Survey says: ${{ steps.is_latest.outputs.latest }} !" | ||
echo "Is it minor.latest? Survey says: ${{ steps.is_latest.outputs.minor_latest }} !" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
name: "GitHub package `latest` tag wrangler for containers" | ||
description: "Determines if the published image should include `latest` tags" | ||
|
||
inputs: | ||
package_name: | ||
description: "Package being published (i.e. `dbt-core`, `dbt-redshift`, etc.)" | ||
required: true | ||
new_version: | ||
description: "SemVer of the package being published (i.e. 1.7.2, 1.8.0a1, etc.)" | ||
required: true | ||
github_token: | ||
description: "Auth token for GitHub (must have view packages scope)" | ||
required: true | ||
|
||
outputs: | ||
tags: | ||
description: "A list of tags to associate with this version" | ||
|
||
runs: | ||
using: "docker" | ||
image: "Dockerfile" |
26 changes: 26 additions & 0 deletions
26
.github/actions/latest-wrangler/examples/example_workflow.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
name: Ship it! | ||
on: | ||
workflow_dispatch: | ||
inputs: | ||
package: | ||
description: The package to publish | ||
required: true | ||
version_number: | ||
description: The version number | ||
required: true | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Wrangle latest tag | ||
id: is_latest | ||
uses: ./.github/actions/latest-wrangler | ||
with: | ||
package: ${{ github.event.inputs.package }} | ||
new_version: ${{ github.event.inputs.new_version }} | ||
gh_token: ${{ secrets.GITHUB_TOKEN }} | ||
- name: Print the results | ||
run: | | ||
echo "Is it latest? Survey says: ${{ steps.is_latest.outputs.latest }} !" |
6 changes: 6 additions & 0 deletions
6
.github/actions/latest-wrangler/examples/example_workflow_dispatch.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"inputs": { | ||
"version_number": "1.0.1", | ||
"package": "dbt-redshift" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import os | ||
from packaging.version import Version, parse | ||
import requests | ||
import sys | ||
from typing import List | ||
|
||
|
||
def main(): | ||
package_name: str = os.environ["INPUT_PACKAGE_NAME"] | ||
new_version: Version = parse(os.environ["INPUT_NEW_VERSION"]) | ||
github_token: str = os.environ["INPUT_GITHUB_TOKEN"] | ||
|
||
response = _package_metadata(package_name, github_token) | ||
published_versions = _published_versions(response) | ||
new_version_tags = _new_version_tags(new_version, published_versions) | ||
_register_tags(new_version_tags, package_name) | ||
|
||
|
||
def _package_metadata(package_name: str, github_token: str) -> requests.Response: | ||
url = f"https://api.github.com/orgs/dbt-labs/packages/container/{package_name}/versions" | ||
return requests.get(url, auth=("", github_token)) | ||
|
||
|
||
def _published_versions(response: requests.Response) -> List[Version]: | ||
package_metadata = response.json() | ||
return [ | ||
parse(tag) | ||
for version in package_metadata | ||
for tag in version["metadata"]["container"]["tags"] | ||
if "latest" not in tag | ||
] | ||
|
||
|
||
def _new_version_tags(new_version: Version, published_versions: List[Version]) -> List[str]: | ||
# the package version is always a tag | ||
tags = [str(new_version)] | ||
|
||
# pre-releases don't get tagged with `latest` | ||
if new_version.is_prerelease: | ||
return tags | ||
|
||
if new_version > max(published_versions): | ||
tags.append("latest") | ||
|
||
published_patches = [ | ||
version | ||
for version in published_versions | ||
if version.major == new_version.major and version.minor == new_version.minor | ||
] | ||
if new_version > max(published_patches): | ||
tags.append(f"{new_version.major}.{new_version.minor}.latest") | ||
|
||
return tags | ||
|
||
|
||
def _register_tags(tags: List[str], package_name: str) -> None: | ||
fully_qualified_tags = ",".join([f"ghcr.io/dbt-labs/{package_name}:{tag}" for tag in tags]) | ||
github_output = os.environ.get("GITHUB_OUTPUT") | ||
with open(github_output, "at", encoding="utf-8") as gh_output: | ||
gh_output.write(f"fully_qualified_tags={fully_qualified_tags}") | ||
|
||
|
||
def _validate_response(response: requests.Response) -> None: | ||
message = response["message"] | ||
if response.status_code != 200: | ||
print(f"Call to GitHub API failed: {response.status_code} - {message}") | ||
sys.exit(1) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |