diff --git a/.github/README.md b/.github/README.md new file mode 100644 index 0000000..0ec6098 --- /dev/null +++ b/.github/README.md @@ -0,0 +1,32 @@ +# CI/CD + +Since we're hosting our source code on GitHub, we'll leverage GitHub Actions to automate our CI/CD pipeline. + +GitHub's pipelines are written in YAML files and located within a special directory called `.github`. This directory +contains two subdirectories, [workflows and actions](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions). +Which are used to define the CI/CD pipeline and to create custom actions, respectively. + +## Workflows + +### [check-docker-build.yaml](./workflows/check-docker-build.yaml) + +This workflow runs on every pull request and checks if the Docker image can be built successfully. It's a good practice +to check if the Docker image can be built before merging the pull request to the `main` branch. + +We'll leverage the following reusable actions from GitHub's marketplace to build the image. + +- [docker/build-push-action](https://github.com/docker/build-push-action): Builds and pushes the Docker image. + +### [publish-docker-image.yaml](./workflows/publish-docker-image.yaml) + +This workflow is triggered when a new commit is pushed to the `main` branch. It builds the Docker image and pushes it +to the Container Registry. In our case, we'll use the [GitHub Container Registry](https://docs.github.com/en/packages/guides/about-github-container-registry) +and the [Docker Hub Container Registry](https://www.docker.com/products/docker-hub/) as examples. + +We'll leverage the following reusable actions from GitHub's marketplace to build and push the image. + +- [docker/login-action](https://github.com/docker/login-action): For authenticating with the Docker Hub and the GitHub Container Registry. + Make sure to provide the right credentials to authenticate with your registry. +- [docker/metadata-action](https://github.com/docker/metadata-action): Extracts metadata from the Docker image. +- [docker/build-push-action](https://github.com/docker/build-push-action): Builds and pushes the Docker image. + diff --git a/.github/workflows/check-docker-build.yaml b/.github/workflows/check-docker-build.yaml new file mode 100644 index 0000000..4304ee3 --- /dev/null +++ b/.github/workflows/check-docker-build.yaml @@ -0,0 +1,18 @@ +name: "Check Docker build" +on: + pull_request: {} + +jobs: + build: + name: "Build docker image" + runs-on: ubuntu-latest + steps: + - name: "Checkout" + uses: actions/checkout@v4 + + - name: "Docker build" + uses: docker/build-push-action@v5 + with: + context: ./my-awesome-app + push: false + tags: my-awesome-app:latest diff --git a/.github/workflows/publish-docker-image.yaml b/.github/workflows/publish-docker-image.yaml new file mode 100644 index 0000000..4a88764 --- /dev/null +++ b/.github/workflows/publish-docker-image.yaml @@ -0,0 +1,48 @@ +name: "Publish Docker image" +on: + push: + branches: + - main + +jobs: + publish: + name: "Build and publish Docker image" + runs-on: ubuntu-latest + steps: + - name: "Checkout" + uses: actions/checkout@v4 + + - name: "Login to Docker Hub" + uses: docker/login-action@v3 + with: + username: fernandoarteaga + password: ${{ secrets.FERNANDO_DOCKER_HUB_TOKEN }} + + - name: "Login to GitHub Container Registry" + uses: docker/login-action@v3 + with: + registry: "ghcr.io" + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: "Extract metadata (tags, labels) for Docker" + id: meta + uses: docker/metadata-action@v5 + with: + images: | + fernandoarteaga/${{ inputs.image-name }} + ghcr.io/${{ github.repository }}/${{ inputs.image-name }} + flavor: | + latest=auto + tags: | + type=sha + # set latest tag for main branch + type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }} + + - name: "Build and push Docker images" + uses: docker/build-push-action@v5 + with: + context: ./my-awesome-app + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }}