Skip to content

Commit

Permalink
first try
Browse files Browse the repository at this point in the history
  • Loading branch information
gerardcl committed Nov 12, 2023
1 parent 09356c7 commit 07aeabe
Show file tree
Hide file tree
Showing 29 changed files with 1,746 additions and 22 deletions.
48 changes: 48 additions & 0 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: ODS Pipeline Task

on:
push:
branches:
- main
pull_request:

env:
IMAGE_BASE: ${{ github.repository }}
IMAGE_NAME: python-toolset

jobs:
tests:
name: Tests
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
-
name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.19'
-
name: Run tests
run: |
set -o pipefail
make ci | sed ''/PASS/s//$(printf "\033[32mPASS\033[0m")/'' | sed ''/FAIL/s//$(printf "\033[31mFAIL\033[0m")/''
-
name: Log into ghcr.io
if: ${{ github.event_name != 'pull_request' }}
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Push images to ghcr.io
if: ${{ github.event_name != 'pull_request' }}
run: |
echo "::group::Push ${IMAGE_NAME} to ghcr.io"
docker tag localhost:5000/ods-pipeline/${IMAGE_NAME}:latest ghcr.io/${IMAGE_BASE,,}/${IMAGE_NAME}:latest
docker push ghcr.io/${IMAGE_BASE,,}/${IMAGE_NAME}:latest
echo "::endgroup::"
47 changes: 47 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Release images
on:
release:
types:
- released

env:
REGISTRY: ghcr.io
IMAGE_BASE: ${{ github.repository }}
IMAGE_NAME: python-toolset

jobs:
build:
name: Build and release images
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3

- id: createImageTag
name: Create image tag
run: |
IMAGE_TAG=$(echo ${{ github.event.release.tag_name }} | sed 's/v//')
echo "imageTag=$IMAGE_TAG" >> $GITHUB_OUTPUT
- id: createImageBase
run: |
echo "imageBase=${IMAGE_BASE,,}" >> $GITHUB_OUTPUT
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v2

- name: Log into registry ${{ env.REGISTRY }}
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and release Docker image
id: build-and-push
uses: docker/build-push-action@v4
with:
context: .
file: build/images/Dockerfile.${{env.IMAGE_NAME}}
push: true
tags: ${{env.REGISTRY}}/${{steps.createImageBase.outputs.imageBase}}/${{env.IMAGE_NAME}}:${{steps.createImageTag.outputs.imageTag}}
22 changes: 1 addition & 21 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,21 +1 @@
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

# Go workspace file
go.work
.ods/
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Note that changes which ONLY affect documentation or the testsuite will not be
listed in the changelog.

## [Unreleased]

## [0.1.0] - 2023-11-10

Initial version.

NOTE: This version is based on v0.13.2 of the task `ods-build-python` in the [ods-pipeline](https://github.com/opendevstack/ods-pipeline) repository.
60 changes: 60 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
SHELL = /bin/bash
.SHELLFLAGS := -eu -o pipefail -c
.DELETE_ON_ERROR:
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules

##@ General

# help target is based on https://github.com/operator-framework/operator-sdk/blob/master/release/Makefile.
.DEFAULT_GOAL := help
help: ## Show this help screen.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-25s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
.PHONY: help

.PHONY: lint-shell

##@ Building

images: image-python-toolset ## Build images.
.PHONY: images

image-python-toolset: ## Build python-toolset image.
docker build \
-f build/images/Dockerfile.python-toolset \
-t localhost:5000/ods-pipeline/python-toolset \
.
.PHONY: image-python-toolset

tasks: ## Render tasks. Use VERSION=1.0.0 make tasks to render specific version.
go run github.com/opendevstack/ods-pipeline/cmd/taskmanifest \
-data ImageRepository=ghcr.io/opendevstack/ods-pipeline-python \
-data Version=$$(cat version) \
-template build/tasks/build.yaml \
-destination tasks/build.yaml
.PHONY: tasks

docs: tasks ## Render documentation for tasks.
go run github.com/opendevstack/ods-pipeline/cmd/taskdoc \
-task tasks/build.yaml \
-description build/docs/build.adoc \
-destination docs/build.adoc
.PHONY: docs

##@ Testing

test: test-e2e ## Run complete testsuite.
.PHONY: test

test-e2e: ## Run testsuite of end-to-end task runs.
go test -v -count=1 -timeout 10m ./test/e2e/...
.PHONY: test-e2e

##@ CI

check-docs: docs ## Check docs are up-to-date
@printf "Docs / tasks are " && git diff --quiet docs tasks && echo "up-to-date." || (echo "not up-to-date! Run 'make docs' to update."; false)
.PHONY: check-docs

ci: check-docs test ## Run CI tasks
.PHONY: ci
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,26 @@
# ods-pipeline-python
# ods-pipeline-python

[![Tests](https://github.com/opendevstack/ods-pipeline-python/actions/workflows/main.yaml/badge.svg)](https://github.com/opendevstack/ods-pipeline-python/actions/workflows/main.yaml)

Tekton task for use with [ODS Pipeline](https://github.com/opendevstack/ods-pipeline) to build applications with Python.

## Usage

```yaml
tasks:
- name: build
taskRef:
resolver: git
params:
- { name: url, value: https://github.com/opendevstack/ods-pipeline-python.git }
- { name: revision, value: v0.1.0 }
- { name: pathInRepo, value: tasks/build.yaml }
workspaces:
- { name: source, workspace: shared-workspace }
```
See the [documentation](https://github.com/opendevstack/ods-pipeline-python/blob/main/docs/build.adoc) for details and available parameters.
## About this repository
`docs` and `tasks` are generated directories from recipes located in `build`. See the `Makefile` target for how everything fits together.
21 changes: 21 additions & 0 deletions build/docs/build.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Builds Python applications.

The exact build recipe can be found at
link:https://github.com/opendevstack/ods-pipeline-python/blob/main/build/images/scripts/build.sh[build/images/scripts/build.sh].

In particular, the Python source files are expected to be located in `src`.

The following artifacts are generated by the build task and placed into `.ods/artifacts/`

* `code-coverage/`
** `coverage.xml`
* `xunit-reports/`
** `report.xml`
Instead of the built-in script, one can also specify a build script located
in the Git repository using the `build-script` task parameter. This allows
full control of building and testing, including any generation of artifacts.
Note that some other task parameters have no effect when a custom build
script is used, unless they are handled properly in the script. At a
minimum, the custom script should place its outputs in the directory
identified by `output-dir`.
24 changes: 24 additions & 0 deletions build/images/Dockerfile.python-toolset
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM registry.access.redhat.com/ubi8/python-39:1

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

RUN pip3 config set global.cert /etc/ssl/certs/ca-bundle.crt

USER root

# Add scripts
COPY build/images/scripts/build.sh /usr/local/bin/build-python
ADD https://raw.githubusercontent.com/opendevstack/ods-pipeline/v0.14.0.1/build/images/scripts/cache-build.sh /usr/local/bin/cache-build
ADD https://raw.githubusercontent.com/opendevstack/ods-pipeline/v0.14.0.1/build/images/scripts/copy-build-if-cached.sh /usr/local/bin/copy-build-if-cached
ADD https://raw.githubusercontent.com/opendevstack/ods-pipeline/v0.14.0.1/build/images/scripts/copy-artifacts.sh /usr/local/bin/copy-artifacts
RUN chmod +x /usr/local/bin/build-python && \
chmod +x /usr/local/bin/cache-build && \
chmod +x /usr/local/bin/copy-build-if-cached && \
chmod +x /usr/local/bin/copy-artifacts

VOLUME /workspace/source
# Ensure that file permissions do not prevent Git checkout into workspace.
# See https://git-scm.com/docs/git-config/#Documentation/git-config.txt-safedirectory.
RUN git config --system --add safe.directory '/workspace/source'

USER 1001
87 changes: 87 additions & 0 deletions build/images/scripts/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/bin/bash
set -eu

urlencode() {
local LC_COLLATE=C
local length="${#1}"
for (( i = 0; i < length; i++ )); do
local c="${1:$i:1}"
case $c in
[a-zA-Z0-9.~_-]) printf '%s' "$c" ;;
*) printf '%%%02X' "'$c" ;;
esac
done
}

MAX_LINE_LENGTH="120"
WORKING_DIR="."
ARTIFACT_PREFIX=""
PRE_TEST_SCRIPT=""
DEBUG="${DEBUG:-false}"

while [ "$#" -gt 0 ]; do
case $1 in

--working-dir) WORKING_DIR="$2"; shift;;
--working-dir=*) WORKING_DIR="${1#*=}";;

--max-line-length) MAX_LINE_LENGTH="$2"; shift;;
--max-line-length=*) MAX_LINE_LENGTH="${1#*=}";;

--pre-test-script) PRE_TEST_SCRIPT="$2"; shift;;
--pre-test-script=*) PRE_TEST_SCRIPT="${1#*=}";;

--debug) DEBUG="$2"; shift;;
--debug=*) DEBUG="${1#*=}";;

*) echo "Unknown parameter passed: $1"; exit 1;;
esac; shift; done

if [ "${DEBUG}" == "true" ]; then
set -x
fi

ROOT_DIR=$(pwd)
tmp_artifacts_dir="${ROOT_DIR}/.ods/tmp-artifacts"
# tmp_artifacts_dir enables keeping artifacts created by this build
# separate from other builds in the same repo to facilitate caching.
rm -rf "${tmp_artifacts_dir}"
if [ "${WORKING_DIR}" != "." ]; then
cd "${WORKING_DIR}"
ARTIFACT_PREFIX="${WORKING_DIR/\//-}-"
fi

echo "Configuring pip to use Nexus (${NEXUS_URL}) ..."
# Remove the protocol segment from NEXUS_URL
NEXUS_HOST=$(echo "${NEXUS_URL}" | sed -E 's/^\s*.*:\/\///g')
if [ -n "${NEXUS_HOST}" ] && [ -n "${NEXUS_USERNAME}" ] && [ -n "${NEXUS_PASSWORD}" ]; then
NEXUS_AUTH="$(urlencode "${NEXUS_USERNAME}"):$(urlencode "${NEXUS_PASSWORD}")"
NEXUS_URL_WITH_AUTH="$(echo "${NEXUS_URL}" | sed -E 's/:\/\//:\/\/'"${NEXUS_AUTH}"@'/g')"
pip3 config set global.index-url "${NEXUS_URL_WITH_AUTH}"/repository/pypi-all/simple
pip3 config set global.trusted-host "${NEXUS_HOST}"
pip3 config set global.extra-index-url https://pypi.org/simple
fi;

echo "Installing test requirements ..."
# shellcheck source=/dev/null
pip install --upgrade pip
pip install -r tests_requirements.txt
pip check

echo "Linting ..."
mypy src
flake8 --max-line-length="${MAX_LINE_LENGTH}" src

if [ -n "${PRE_TEST_SCRIPT}" ]; then
echo "Executing pre-test script ..."
./"${PRE_TEST_SCRIPT}"
fi

echo "Testing ..."
rm report.xml coverage.xml &>/dev/null || true
PYTHONPATH=src python -m pytest --junitxml=report.xml -o junit_family=xunit2 --cov-report term-missing --cov-report xml:coverage.xml --cov=src -o testpaths=tests

mkdir -p "${tmp_artifacts_dir}/xunit-reports"
cp report.xml "${tmp_artifacts_dir}/xunit-reports/${ARTIFACT_PREFIX}report.xml"
mkdir -p "${tmp_artifacts_dir}/code-coverage"
cp coverage.xml "${tmp_artifacts_dir}/code-coverage/${ARTIFACT_PREFIX}coverage.xml"
Loading

0 comments on commit 07aeabe

Please sign in to comment.