├── .github └── workflows │ ├── integration.yml │ └── python.yml ├── Dockerfile ├── LICENSE ├── README.md ├── action.yml └── main.py /.github/workflows/integration.yml: -------------------------------------------------------------------------------- 1 | name: Integration Test 2 | on: [push] 3 | jobs: 4 | build: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@master 8 | - name: Self test 9 | id: selftest 10 | 11 | # Put your action repo here 12 | uses: jacobtomlinson/python-container-action@master 13 | 14 | - name: Check outputs 15 | run: | 16 | test "${{ steps.selftest.outputs.myOutput }}" == "Hello world" 17 | -------------------------------------------------------------------------------- /.github/workflows/python.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | on: [push, pull_request] 3 | jobs: 4 | lint: 5 | name: Lint 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Set up Python 3.7 9 | uses: actions/setup-python@v1 10 | with: 11 | python-version: "3.7" 12 | 13 | - uses: actions/checkout@v1 14 | 15 | - name: Lint 16 | run: | 17 | pip install flake8 18 | flake8 main.py 19 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3-slim AS builder 2 | ADD . /app 3 | WORKDIR /app 4 | 5 | # We are installing a dependency here directly into our app source dir 6 | RUN pip install --target=/app requests 7 | 8 | # A distroless container image with Python and some basics like SSL certificates 9 | # https://github.com/GoogleContainerTools/distroless 10 | FROM gcr.io/distroless/python3-debian10 11 | COPY --from=builder /app /app 12 | WORKDIR /app 13 | ENV PYTHONPATH /app 14 | CMD ["/app/main.py"] 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2018 GitHub, Inc. and contributors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python Container Action Template 2 | 3 | [![Action Template](https://img.shields.io/badge/Action%20Template-Python%20Container%20Action-blue.svg?colorA=24292e&colorB=0366d6&style=flat&longCache=true&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAM6wAADOsB5dZE0gAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAERSURBVCiRhZG/SsMxFEZPfsVJ61jbxaF0cRQRcRJ9hlYn30IHN/+9iquDCOIsblIrOjqKgy5aKoJQj4O3EEtbPwhJbr6Te28CmdSKeqzeqr0YbfVIrTBKakvtOl5dtTkK+v4HfA9PEyBFCY9AGVgCBLaBp1jPAyfAJ/AAdIEG0dNAiyP7+K1qIfMdonZic6+WJoBJvQlvuwDqcXadUuqPA1NKAlexbRTAIMvMOCjTbMwl1LtI/6KWJ5Q6rT6Ht1MA58AX8Apcqqt5r2qhrgAXQC3CZ6i1+KMd9TRu3MvA3aH/fFPnBodb6oe6HM8+lYHrGdRXW8M9bMZtPXUji69lmf5Cmamq7quNLFZXD9Rq7v0Bpc1o/tp0fisAAAAASUVORK5CYII=)](https://github.com/jacobtomlinson/python-container-action) 4 | [![Actions Status](https://github.com/jacobtomlinson/python-container-action/workflows/Lint/badge.svg)](https://github.com/jacobtomlinson/python-container-action/actions) 5 | [![Actions Status](https://github.com/jacobtomlinson/python-container-action/workflows/Integration%20Test/badge.svg)](https://github.com/jacobtomlinson/python-container-action/actions) 6 | 7 | This is a template for creating GitHub actions and contains a small Python application which will be built into a minimal [Container Action](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-a-docker-container-action). Our final container from this template is ~50MB, yours may be a little bigger once you add some code. If you want something smaller check out my [go-container-action template](https://github.com/jacobtomlinson/go-container-action/actions). 8 | 9 | In `main.py` you will find a small example of accessing Action inputs and returning Action outputs. For more information on communicating with the workflow see the [development tools for GitHub Actions](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/development-tools-for-github-actions). 10 | 11 | > 🏁 To get started, click the `Use this template` button on this repository [which will create a new repository based on this template](https://github.blog/2019-06-06-generate-new-repositories-with-repository-templates/). 12 | 13 | ## Usage 14 | 15 | Describe how to use your action here. 16 | 17 | ### Example workflow 18 | 19 | ```yaml 20 | name: My Workflow 21 | on: [push, pull_request] 22 | jobs: 23 | build: 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@master 27 | - name: Run action 28 | 29 | # Put your action repo here 30 | uses: me/myaction@master 31 | 32 | # Put an example of your mandatory inputs here 33 | with: 34 | myInput: world 35 | ``` 36 | 37 | ### Inputs 38 | 39 | | Input | Description | 40 | |------------------------------------------------------|-----------------------------------------------| 41 | | `myInput` | An example mandatory input | 42 | | `anotherInput` _(optional)_ | An example optional input | 43 | 44 | ### Outputs 45 | 46 | | Output | Description | 47 | |------------------------------------------------------|-----------------------------------------------| 48 | | `myOutput` | An example output (returns 'Hello world') | 49 | 50 | ## Examples 51 | 52 | > NOTE: People ❤️ cut and paste examples. Be generous with them! 53 | 54 | ### Using the optional input 55 | 56 | This is how to use the optional input. 57 | 58 | ```yaml 59 | with: 60 | myInput: world 61 | anotherInput: optional 62 | ``` 63 | 64 | ### Using outputs 65 | 66 | Show people how to use your outputs in another action. 67 | 68 | ```yaml 69 | steps: 70 | - uses: actions/checkout@master 71 | - name: Run action 72 | id: myaction 73 | 74 | # Put your action name here 75 | uses: me/myaction@master 76 | 77 | # Put an example of your mandatory arguments here 78 | with: 79 | myInput: world 80 | 81 | # Put an example of using your outputs here 82 | - name: Check outputs 83 | run: | 84 | echo "Outputs - ${{ steps.myaction.outputs.myOutput }}" 85 | ``` -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: "Python Container Action Template" 2 | description: "Get started with Python Container actions" 3 | author: "Jacob Tomlinson" 4 | inputs: 5 | myInput: 6 | description: "Input to use" 7 | default: "world" 8 | outputs: 9 | myOutput: 10 | description: "Output from the action" 11 | runs: 12 | using: "docker" 13 | image: "Dockerfile" 14 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import requests # noqa We are just importing this to prove the dependency installed correctly 3 | 4 | # Set the output value by writing to the outputs in the Environment File, mimicking the behavior defined here: 5 | # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter 6 | def set_github_action_output(output_name, output_value): 7 | f = open(os.path.abspath(os.environ["GITHUB_OUTPUT"]), "a") 8 | f.write(f'{output_name}={output_value}') 9 | f.close() 10 | 11 | def main(): 12 | my_input = os.environ["INPUT_MYINPUT"] 13 | 14 | my_output = f'Hello {my_input}' 15 | 16 | set_github_action_output('myOutput', my_output) 17 | 18 | 19 | if __name__ == "__main__": 20 | main() 21 | --------------------------------------------------------------------------------