diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml new file mode 100644 index 0000000..77bab76 --- /dev/null +++ b/.github/workflows/ci-pipeline.yml @@ -0,0 +1,52 @@ +name: CI Github Actions +on: + push: + branches: + - module_8 + pull_request: + branches: + - module_8 + +jobs: + + build: + + name: Build and test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: docker build --target test --tag todo-app:test . + - run: docker run todo-app:test tests + - run: docker run -e TRELLO_API_KEY=${{ secrets.TRELLO_API_KEY }} -e TRELLO_API_SECRET=${{ secrets.TRELLO_API_SECRET }} -e TRELLO_BOARD_ID=${{ secrets.TRELLO_BOARD_ID }} todo-app:test tests_e2e + + - name: Send status to Slack workflow + id: slack + uses: act10ns/slack@v1 + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + with: + status: ${{ job.status }} + message: "GitHub Actions Result: ${{ job.status }}\n${{ github.event.pull_request.html_url }}" + + production: + needs: build + name: Push to DockerHub + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/module_8' && github.event_name == 'push' + steps: + - uses: actions/checkout@v2 + + - name: Setting up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to DockerHub + run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin + + - name: Push Image to DockerHub + uses: docker/build-push-action@v3 + with: + context: . + file: ./Dockerfile + target: production + push: true + tags: ${{ secrets.DOCKERHUB_USERNAME }}/todoapp:latest diff --git a/Dockerfile b/Dockerfile index 1386faf..e3ab512 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,12 +5,12 @@ WORKDIR /opt COPY . /opt RUN pip install poetry COPY pyproject.toml poetry.lock /opt/ -RUN poetry install +RUN poetry config virtualenvs.create false --local && poetry install COPY ./todo_app /opt/todo_app/ FROM base as production EXPOSE 80 -CMD poetry run gunicorn "todo_app.app:create_app()" -b 0.0.0.0:80 +CMD poetry run gunicorn "todo_app.app:create_app()" -b 0.0.0.0:${PORT:-5000} #ENTRYPOINT ["sh", "/opt/gunicorn.sh"] FROM base as development @@ -30,4 +30,4 @@ RUN unzip /tmp/chromedriver.zip chromedriver -d /opt/todo_app ENV PATH="${PATH}:/opt/todo_app" EXPOSE 5000 -CMD ["poetry", "run", "pytest"] +ENTRYPOINT ["poetry", "run", "pytest"] diff --git a/README.md b/README.md index e82dec9..b175cdb 100644 --- a/README.md +++ b/README.md @@ -81,8 +81,47 @@ ansible-playbook my-playbook.yml -i my-inventory You will be prompted for the trello api key, secret, and board ID, which you can paste in. ## Docker -You can run 'docker-compose up' to create the Dev, Prod, and Test images. -The test results will output to the terminal. +You can run 'docker-compose up' to create the Dev, Prod, and Test images. The test results will output to the terminal. -For Prod - http://localhost -For Dev - http://localhost:5000 +For Prod - http://localhost For Dev - http://localhost:5000 + +To run the commands manually you can use: + +docker build --target test --tag todo-app:test . + +docker run todo-app:test tests +docker run --env-file .env todo-app:test tests_e2e + +## Secrets +You must define the following secrets in GitHub Secrets section: + +For the board to work: +TRELLO_API_KEY +TRELLO_API_SECRET +TRELLO_BOARD_ID + +For slack notifications: +SLACK_WEBHOOK_URL +From thew Incoming WebHooks app in the slack app directory. + +For DockerHub +DOCKERHUB_PASSWORD +DOCKERHUB_USERNAME + +## Heroku: +My app name is +https://markdossantos-module8.herokuapp.com/ + +To deploy to Heroku from DockerHub you will need to retag the Image: +docker tag registry.heroku.com//web + +Push the image to DockerHub +docker push registry.heroku.com//web + +Release the application +heroku container:release web -a + +For automation in your CI pipeline you will need to create an API key with: +heroku authorizations:create +And save the key in Github Secrets as: +HEROKU_API_KEY \ No newline at end of file diff --git a/tests_e2e/test_e2e.py b/tests_e2e/test_e2e.py index 4aa3e7e..ea5c7bb 100644 --- a/tests_e2e/test_e2e.py +++ b/tests_e2e/test_e2e.py @@ -104,3 +104,4 @@ def find_task_in_section(section_name, driver): section = driver.find_element_by_xpath(f"//*[@data-test-id='{section_name}']") tasks = section.find_elements_by_xpath("//*[@data-test-class='task']") return next(task for task in tasks if task.find_element_by_xpath("//*[contains(text(), 'Test Task')]") is not None) + \ No newline at end of file