Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
eveleighoj authored Feb 21, 2025
0 parents commit cd06d8c
Show file tree
Hide file tree
Showing 15 changed files with 345 additions and 0 deletions.
93 changes: 93 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: Deploy

on:
push:
workflow_dispatch:
inputs:
environment:
type: environment
description: The environment to deploy to.

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v4
with:
python-version: 3.8
- run: make init
- run: make lint

test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-python@v4
with:
python-version: 3.8

- run: make init

- name: run tests
run: |
make test
detect-environments:
runs-on: ubuntu-latest
outputs:
environments: ${{ steps.environments.outputs.result }}
if: github.ref_name == 'main'
needs: [lint,test]
steps:
- uses: actions/github-script@v6
id: environments
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
result-encoding: json
script: |
if (context.payload?.inputs?.environment) return [context.payload?.inputs?.environment];
const {data: {environments}} =
await github.request(`GET /repos/${process.env.GITHUB_REPOSITORY}/environments`);
return environments.map(e => e.name)
deploy:
runs-on: ubuntu-latest
env:
DOCKER_REPO: ${{ secrets.DEPLOY_DOCKER_REPOSITORY }}
needs: [detect-environments]
strategy:
matrix:
environment: ${{ fromJSON(needs.detect-environments.outputs.environments) }}
environment: ${{ matrix.environment }}
if: github.ref_name == 'main'
steps:
- uses: actions/checkout@v4

- id: vars
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT

- uses: aws-actions/configure-aws-credentials@v1-node16
with:
aws-access-key-id: ${{ secrets.DEPLOY_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.DEPLOY_AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-2

- uses: aws-actions/amazon-ecr-login@v1

- run: docker pull $DOCKER_REPO:latest || echo "no current latest image"

- run: docker build -t $DOCKER_REPO:${{ steps.vars.outputs.sha_short }} .
working-directory: ./task

- run: docker tag $DOCKER_REPO:${{ steps.vars.outputs.sha_short }} $DOCKER_REPO:latest

- run: docker push $DOCKER_REPO:${{ steps.vars.outputs.sha_short }}

- run: docker push $DOCKER_REPO:latest
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# general python files that aren't needed
__pycache__/
*.py[cod]
*$py.class
.DS_Store
.ipynb_checkpoints/
.venv
.cache
18 changes: 18 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# syntax=docker/dockerfile:1

FROM python:3.8-slim-bookworm
WORKDIR /
RUN apt-get update
RUN apt-get upgrade -y

COPY requirements/requirements.txt /requirements.txt
RUN pip install --upgrade pip
RUN pip install --upgrade -r requirements.txt

COPY task /task
# USER task
# RUN chown task:task -R /task

WORKDIR /task

ENTRYPOINT ["sh","./run.sh"]
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Digital Land

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
29 changes: 29 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

.PHONY: \
compile \
init \
run-task \
test \
test-unit \
test-acceptance

compile ::
python -m piptools compile --output-file=requirements/requirements.txt requirements/requirements.in
python -m piptools compile --output-file=requirements/test-requirements.txt requirements/test-requirements.in

init ::
pip install --upgrade pip
pip install -r requirements/test-requirements.txt

run-task ::
cd task; \
./run.sh;

test: test-unit test-acceptance

test-unit:
python -m pytest tests/unit

test-acceptance:
# run bats test of the script
bats tests/acceptance/test_run.bats
88 changes: 88 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# ecs-task-template
A template repo for making ecs tasks that can be deployed into our infrastructure. We expect to continually improve this template as we improve our code so there may be some differences between this and older task repositories.

Ther emay be good reasons to change the structure of this repo to suit your task. When this happens it's worth noting in the README the reason for the change.

## How To Use This Template

Files/Folders:

```
requirements - Folder to contain python requirements, these will be added to the image
requirements.in - file which piptools can use to generate requirements file
requirements.txt - generated using piptools, acts as a lockfile for the python dependencies
task - Folder containing the source code for the task. This folder is copied into the docker container and is the working directory
run.sh - the shell script that is ran when the container is started
.... - other files needed to support run.sh
tests - Foder containing the tests for the task these will depend ont he task itself but should follow testing guidance.
Dockerfile - file that is used to
Makefile - use file containing make targets for running the task locally
README.md - contains detaills on the ecs task, including information on dependencies and how to run locally
```

1. Create a repo from the template
2. Alter code, add tests update README (Remove this section and update the others)
3. reach out to infrastructure to register task and create definition
4. deploy into development to check it works
5. deploy to staging and production

## Dependencies


## how to run locally

this task can be ran either with or without docker the instructions for either are below

### Without Docker

set up dependencies:

* create a virtual environment for python and activate it
* run make init to install local
* run make run-task

then because the task needs to be ran from the task directory you need to change into the task directorry

`cd task`

then the task can be ran using the entrypoint scrript

`./run.sh`

it can also be ran without changing directory by using the make commands

`make run-task`

### With Docker

With docker we have created a docker compose file which allows you to run it locally . First install the depencies:

* Install docker.

now run the docker compose code using

```
docker compose up
```

this will start the container and print the logs into the terminal.


## How to run tests

Tests run locally, there are a few depencies to have innstalled to use them:

* create a virtual environment
* run make init to install the test dependencies
* install BATS to test the bash scripts used to trigger/orchestrate cde within the container

tests can then be ran using

`make test`

there are individual make targets for unit and acceptance tests

`makw unit`
`make acceptance`


16 changes: 16 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: '3.8'

services:
run-task:
build:
context: .
dockerfile: Dockerfile
container_name: run-task
# can be used if there's an envionment file that needs loading
# environment:
# - ENV_FILE=.env
# volumes:
# - .:/usr/src/app
ports:
- "8000:8000" # Adjust this if your application needs to expose ports
# command: sh docker/entrypoint.sh all # Adjust this based on the entrypoint target you want to run
1 change: 1 addition & 0 deletions requirements/requirements.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
click
8 changes: 8 additions & 0 deletions requirements/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#
# This file is autogenerated by pip-compile with Python 3.8
# by the following command:
#
# pip-compile --output-file=requirements/requirements.txt requirements/requirements.in
#
click==8.1.7
# via -r requirements/requirements.in
2 changes: 2 additions & 0 deletions requirements/test-requirements.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-r requirements.txt
pytest
20 changes: 20 additions & 0 deletions requirements/test-requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#
# This file is autogenerated by pip-compile with Python 3.8
# by the following command:
#
# pip-compile --output-file=requirements/test-requirements.txt requirements/test-requirements.in
#
click==8.1.7
# via -r requirements/requirements.txt
exceptiongroup==1.2.2
# via pytest
iniconfig==2.0.0
# via pytest
packaging==24.1
# via pytest
pluggy==1.5.0
# via pytest
pytest==8.3.2
# via -r requirements/test-requirements.in
tomli==2.0.1
# via pytest
17 changes: 17 additions & 0 deletions task/hello.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import click

def hello(name):
print(f'hello {name}')

@click.command()
@click.option(
"--name",
type=str,
help="Name to print to the console",
)
def hello_command(name):
hello(name)


if __name__ == "__main__":
hello_command()
1 change: 1 addition & 0 deletions task/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python -m hello --name="Owen"
15 changes: 15 additions & 0 deletions tests/acceptance/test_run.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bats

# test_run_python_script.bats

# Test if the Bash script runs the Python script and doesn't fail
@test "run_.sh prints" {
# change to the task directory
cd task

# Run the Bash script and capture the output
run ./run.sh

# Assert that the exit status is 0 (success)
[ "$status" -eq 0 ]
}
8 changes: 8 additions & 0 deletions tests/unit/test_hello.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from task.hello import hello

def test_hello_prints_statement(capsys):
hello(name='Owen')
captured = capsys.readouterr()

# Assert that the output was printed
assert captured.out is not None

0 comments on commit cd06d8c

Please sign in to comment.