From cdb224057e949e940ad5118a88aeaa8f0e76daac Mon Sep 17 00:00:00 2001 From: Joaquin Trillo Date: Mon, 16 Dec 2024 11:45:47 +0100 Subject: [PATCH 1/3] Bootcamp update 2024 --- .github/workflows/cd-docker.yml | 6 +- .github/workflows/cd-using-docker-actions.yml | 72 ++++++++++++++ .github/workflows/reusable-node-build.yml | 2 +- .github/workflows/test-custom-action.yml | 3 +- .start-code/hangman-api/Dockerfile | 3 +- 01-setup-ci/readme.md | 5 - 04-working-with-build-artifacts/readme.md | 26 +++-- 06-service-containers/readme.md | 13 ++- 08-continous-delivery/readme.md | 30 +++--- .../01-creating-reusable-workflow/readme.md | 4 +- 09-workflow-calls/readme.md | 6 +- 10-custom-action/action-files/action.yml | 6 +- 10-custom-action/action-files/index.js | 40 +++++--- 10-custom-action/readme.md | 99 +++++++++++++++---- 14 files changed, 242 insertions(+), 73 deletions(-) create mode 100644 .github/workflows/cd-using-docker-actions.yml diff --git a/.github/workflows/cd-docker.yml b/.github/workflows/cd-docker.yml index 5aeb494..a678220 100644 --- a/.github/workflows/cd-docker.yml +++ b/.github/workflows/cd-docker.yml @@ -23,7 +23,7 @@ jobs: # run: | # npm ci # npm run build --if-present - # - uses: actions/upload-artifact@v3 + # - uses: actions/upload-artifact@v4 # with: # name: build-code # path: hangman-api/dist/ @@ -34,14 +34,14 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: build-code path: hangman-api/dist/ - name: Build and Push Docker Image working-directory: ./hangman-api env: - DOCKER_USER: "jaimesalas" + DOCKER_USER: "jaimesalas" # DOCKER_REPOSITORY: "hangman-api" DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} run: | diff --git a/.github/workflows/cd-using-docker-actions.yml b/.github/workflows/cd-using-docker-actions.yml new file mode 100644 index 0000000..67474ad --- /dev/null +++ b/.github/workflows/cd-using-docker-actions.yml @@ -0,0 +1,72 @@ +name: Docker Image hangman API CD (using Docker actions) + +on: + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: hangman-api/package-lock.json + - name: build + working-directory: ./hangman-api + run: | + npm ci + npm run build --if-present + - uses: actions/upload-artifact@v4 + with: + name: build-code + path: hangman-api/dist/ + + # delivery: + # runs-on: ubuntu-latest + # needs: build + + # steps: + # - uses: actions/checkout@v4 + # - uses: actions/download-artifact@v4 + # with: + # name: build-code + # path: hangman-api/dist/ + # - name: Build and Push Docker Image + # working-directory: ./hangman-api + # env: + # DOCKER_USER: "jaimesalas" # + # DOCKER_REPOSITORY: "hangman-api" + # DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + # run: | + # echo $DOCKER_PASSWORD | docker login --username $DOCKER_USER --password-stdin + # image=$DOCKER_USER/$DOCKER_REPOSITORY:$(date +%s) + # docker build -t $image -f Dockerfile.workflow . + # docker push $image + + delivery: + runs-on: ubuntu-latest + needs: build + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + - name: Download dist folder as artifact + uses: actions/download-artifact@v4 + - name: Docker Hub login + uses: docker/login-action@v3 + with: + # registry: by default is set to Docker Hub + username: jtrillo # + password: ${{ secrets.DOCKER_PASSWORD }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Build and push Docker Image + uses: docker/build-push-action@v5 + with: + context: ./hangman-api + push: true + tags: jtrillo/hangman-api-actions:latest # + file: ./hangman-api/Dockerfile.workflow diff --git a/.github/workflows/reusable-node-build.yml b/.github/workflows/reusable-node-build.yml index dab8f32..93a42fa 100644 --- a/.github/workflows/reusable-node-build.yml +++ b/.github/workflows/reusable-node-build.yml @@ -26,7 +26,7 @@ jobs: run: | npm ci npm run build --if-present - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: build-code path: ${{ inputs.working-directory }}/dist/ diff --git a/.github/workflows/test-custom-action.yml b/.github/workflows/test-custom-action.yml index 5bc56df..84b7512 100644 --- a/.github/workflows/test-custom-action.yml +++ b/.github/workflows/test-custom-action.yml @@ -13,6 +13,7 @@ jobs: uses: jtrillo/get-commodity-price@v1.0.1 with: commodity: silver + currency: EUR # Use the output from 'commodity_price' step - name: Get the output price - run: echo "Price per ounce is ${{ steps.commodity_price.outputs.price }} USD" + run: echo "Price per ounce is ${{ steps.commodity_price.outputs.price }} ${{ steps.commodity_price.inputs.currency }}" diff --git a/.start-code/hangman-api/Dockerfile b/.start-code/hangman-api/Dockerfile index a2e24e3..4457cec 100644 --- a/.start-code/hangman-api/Dockerfile +++ b/.start-code/hangman-api/Dockerfile @@ -23,5 +23,4 @@ ENV NODE_ENV=production RUN npm install - -CMD ["npm", "start"] +CMD ["npm", "start"] \ No newline at end of file diff --git a/01-setup-ci/readme.md b/01-setup-ci/readme.md index 5298f41..84de6c2 100644 --- a/01-setup-ci/readme.md +++ b/01-setup-ci/readme.md @@ -31,8 +31,6 @@ jobs: whoami pwd node -v - - ``` Let's commit this file to a new branch: @@ -149,7 +147,6 @@ jobs: - whoami - pwd - node -v - ``` ```yaml @@ -210,9 +207,7 @@ jobs: run: | npm ci npm run build --if-present - ls ./dist npm test - ``` * With `paths` we filter the directories that are able to trigger a new workflow. diff --git a/04-working-with-build-artifacts/readme.md b/04-working-with-build-artifacts/readme.md index 3204f68..0020631 100644 --- a/04-working-with-build-artifacts/readme.md +++ b/04-working-with-build-artifacts/readme.md @@ -47,10 +47,11 @@ jobs: npm ci npm run build --if-present # diff # - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: dependencies path: hangman-api/node_modules/ + include-hidden-files: true # diff # ``` @@ -72,10 +73,11 @@ jobs: run: | npm ci npm run build --if-present - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: dependencies path: hangman-api/node_modules/ + include-hidden-files: true test: runs-on: ubuntu-latest @@ -84,14 +86,17 @@ jobs: steps: - uses: actions/checkout@v4 # diff - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: dependencies path: hangman-api/node_modules - # diff + include-hidden-files: true - name: test working-directory: ./hangman-api - run: npm test # npm ci is not needed here + run: | + chmod -R +x node_modules + npm test + # diff ``` Let's push the changes done. @@ -104,7 +109,9 @@ git push And trigger the workflow from project site. -If we check the workflow, we will notice that is taking a long time to resolve the dependencies upload. This is not the way to manage this, let's try something different. +**DEPRECATED.** ~~If we check the workflow, we will notice that is taking a long time to resolve the dependencies upload~~. **Both actions in version 4 improve significatly the performance. Check this article: **. + +However, this approach is not the proper way to manage this, let's try something different: using the cache. * [Caching dependencies to speed up workflows](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows) @@ -127,10 +134,11 @@ jobs: run: | npm ci npm run build --if-present -- - uses: actions/upload-artifact@v3 +- - uses: actions/upload-artifact@v4 - with: - name: dependencies - path: hangman-api/node_modules/ +- include-hidden-files: true test: runs-on: ubuntu-latest @@ -138,16 +146,18 @@ jobs: steps: - uses: actions/checkout@v4 -- - uses: actions/download-artifact@v3.0.0 +- - uses: actions/download-artifact@v4 - with: - name: dependencies - path: hangman-api/node_modules +- include-hidden-files: true + - uses: actions/setup-node@v4 + with: + node-version: 16 - name: test working-directory: ./hangman-api run: | +- chmod -R +x node_modules + npm ci npm test ``` diff --git a/06-service-containers/readme.md b/06-service-containers/readme.md index 28a9d34..b5c99db 100644 --- a/06-service-containers/readme.md +++ b/06-service-containers/readme.md @@ -8,7 +8,7 @@ The previous solution for integration test works, but have some downsides. * Dockerfile.migrations * Dockerfile.test-integration -This code is not related with our solution, is just there to solve the CI issue. Well is not the end of the world, but is thera another way that we can solve this? Let's introduce [Service Containers](https://docs.github.com/en/actions/using-containerized-services/about-service-containers) +This code is not related with our solution, it is just there to solve the CI issue. Well, this is not the end of the world, but is there another way to execute the integration tests without adding these files? Let's introduce [Service Containers](https://docs.github.com/en/actions/using-containerized-services/about-service-containers) > **About service containers** - Service containers are Docker containers that provide a simple and portable way for you to host services that you might need to test or operate your application in a workflow. For example, your workflow might need to run integration tests that require access to a database and memory cache. @@ -71,7 +71,7 @@ git commit -m "added database relationships step" git push ``` -* Run the workflow manually from GiHub website. +* Run the workflow manually from GitHub website. If everything goes right we must see and output as follows: @@ -138,3 +138,12 @@ Snapshots: 0 total Time: 3.519 s Ran all test suites. ``` + +* Before moving on, let's delete files added in the previous demo (`wait-for-it.sh`, `test-integration.yml`, `Dockerfile.migrations` and `Dockerfile.test-integration`) to verify that service containers approach does not need them. + +```bash +rm wait-for-it.sh test-integration.yml Dockerfile.migrations Dockerfile.test-integration +git add . +git commit -m "Delete no longer required files to run the integration tests" +git push +``` diff --git a/08-continous-delivery/readme.md b/08-continous-delivery/readme.md index e00dc69..3bd7180 100644 --- a/08-continous-delivery/readme.md +++ b/08-continous-delivery/readme.md @@ -14,13 +14,13 @@ Before adding the required steps into our workflow, let's try it on local. First from `hangman-api` root directory run: ```bash -docker build -t jaimesalas/hangman-api . +docker build -t /hangman-api . ``` And test by running: ```bash -docker run -d -p 3000:3000 jaimesalas/hangman-api +docker run -d -p 3000:3000 /hangman-api ``` ```bash @@ -31,7 +31,7 @@ We could also push it to Docker Hub ```bash docker login # Just if not already logged -docker push jaimesalas/hangman-api +docker push /hangman-api ``` ## Building the Docker Image in a workflow @@ -115,7 +115,7 @@ CMD ["npm", "start"] We should use the following command to build an image with an specific Node.js version: ```bash -docker build -t jtrillo/hangman-api -f Dockerfile.workflow --build-arg version=20.10-alpine . +docker build -t /hangman-api -f Dockerfile.workflow --build-arg version=20.10-alpine . ``` First, we're going to use the same build job as the one on `ci.yml`. But here we're going to upload the build as an artifact to be used on a new `delivery` job: @@ -144,7 +144,7 @@ jobs: run: | npm ci npm run build --if-present - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: build-code path: hangman-api/dist/ @@ -161,7 +161,7 @@ Now we need to build the image before push it to Docker registry we can do this steps: - uses: actions/checkout@v4 - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: build-code path: hangman-api/dist/ @@ -195,7 +195,7 @@ Ok, almost done. There are prebaked actions to authenticate and push Docker imag + - name: Build and Push Docker Image working-directory: ./hangman-api + env: -+ DOCKER_USER: "jaimesalas" ++ DOCKER_USER: "jaimesalas" # + DOCKER_REPOSITORY: "hangman-api" + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - run: docker build . --file Dockerfile.workflow --tag my-image-name:$(date +%s) @@ -224,8 +224,8 @@ And fire the workflow from GitHub site. If everything works we must see somethin ```console ---> 12c19641de84 Successfully built 12c19641de84 -Successfully tagged jaimesalas/hangman-api:1665501807 -The push refers to repository [docker.io/jaimesalas/hangman-api] +Successfully tagged /hangman-api:1665501807 +The push refers to repository [docker.io//hangman-api] ``` And visit Docker Hub to find out the uploaded image @@ -238,10 +238,10 @@ In this case, we will use actions instead of commands. We are going to make use * [docker/setup-buildx-action](https://github.com/marketplace/actions/docker-setup-buildx) * [docker/build-push-action](https://github.com/marketplace/actions/build-and-push-docker-images) -Let's add a new job to our workflow. +Let's update `delivery` job: ```yaml - buildAndPush: + delivery: runs-on: ubuntu-latest needs: build @@ -249,12 +249,12 @@ Let's add a new job to our workflow. - name: Checkout repo uses: actions/checkout@v4 - name: Download dist folder as artifact - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 - name: Docker Hub login uses: docker/login-action@v3 with: # registry: by default is set to Docker Hub - username: jtrillo + username: jtrillo # password: ${{ secrets.DOCKER_PASSWORD }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -263,7 +263,7 @@ Let's add a new job to our workflow. with: context: ./hangman-api push: true - tags: jtrillo/hangman-api-actions:latest + tags: jtrillo/hangman-api-actions:latest # file: ./hangman-api/Dockerfile.workflow ``` @@ -271,7 +271,7 @@ Push the new changes ```bash git add . -git commit -m "added buildAndPush job" +git commit -m "update delivery job" git push ``` diff --git a/09-workflow-calls/01-creating-reusable-workflow/readme.md b/09-workflow-calls/01-creating-reusable-workflow/readme.md index 5e92932..0389cb1 100644 --- a/09-workflow-calls/01-creating-reusable-workflow/readme.md +++ b/09-workflow-calls/01-creating-reusable-workflow/readme.md @@ -40,7 +40,7 @@ jobs: run: | npm ci npm run build --if-present - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: build-code path: ${{ inputs.working-directory }}/dist/ @@ -75,7 +75,7 @@ jobs: - run: | - npm ci - npm run build --if-present -- - uses: actions/upload-artifact@v3 +- - uses: actions/upload-artifact@v4 - with: - name: build-code - path: hangman-api/dist/ diff --git a/09-workflow-calls/readme.md b/09-workflow-calls/readme.md index 61f8c33..331ae2e 100644 --- a/09-workflow-calls/readme.md +++ b/09-workflow-calls/readme.md @@ -31,10 +31,10 @@ After you add a `workflow_call` trigger, you need to make sure that your reposit There are [limitations](https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations). Some of them are: * **You can't reference a reusable workflow that's in a private repository**. If you have a reusable workflow in a private repository, only other workflows in that private repository can use it. +* **Reusable workflows cant be stacked on top of one another, but there is a limit**. You can connect a maximum of four levels of workflows - that is, the top-level caller workflow and up to three levels of reusable workflows. For example: caller-workflow.yml → called-workflow-1.yml → called-workflow-2.yml → called-workflow-3.yml. Loops in the workflow tree are not permitted. More info [here](https://docs.github.com/en/actions/sharing-automations/reusing-workflows#nesting-reusable-workflows) +* **You can call a maximum of 20 unique reusable workflows from a single worklow file**. This limit includes nested/stacked reusable workflows. -* **Reusable workflows can’t be stacked on top of one another**. You can only have a reusable workflow call another reusable workflow, but you can’t have it reference more than one. - -## Reusable workflows vs.composite actions +## Reusable workflows vs composite actions When we launched reusable workflows, one of the first questions we got was around how they’re different from composite actions. diff --git a/10-custom-action/action-files/action.yml b/10-custom-action/action-files/action.yml index add2848..fb1f93f 100644 --- a/10-custom-action/action-files/action.yml +++ b/10-custom-action/action-files/action.yml @@ -5,9 +5,13 @@ inputs: description: 'Commodity (gold or silver)' required: true default: 'gold' + currency: # id of input + description: 'Currency (USD or EUR)' + required: true + default: 'USD' outputs: price: # id of output description: 'The current price of the select commodity' runs: - using: 'node16' + using: 'node20' main: 'index.js' \ No newline at end of file diff --git a/10-custom-action/action-files/index.js b/10-custom-action/action-files/index.js index 155aec7..b4d9438 100644 --- a/10-custom-action/action-files/index.js +++ b/10-custom-action/action-files/index.js @@ -1,25 +1,41 @@ -const core = require('@actions/core'); -const github = require('@actions/github'); +import { getInput, setOutput, setFailed } from '@actions/core'; +import { context } from '@actions/github'; try { // `commodity` input defined in action metadata file - const commodity = core.getInput('commodity'); - console.log(`Getting current ${commodity} price per ounce...`); + const commodity = getInput('commodity'); + + // Check if input is valid + if (commodity.toLowerCase() !== 'gold' && commodity.toLowerCase() !== 'silver') { + throw new Error(`Commodity ${commodity} is not valid`); + } + + // `currency` input defined in action metadata file + const currency = getInput('currency'); + + // Check if input is valid + if (currency.toUpperCase() !== 'USD' && currency.toUpperCase() !== 'EUR') { + throw new Error(`Currency ${currency} is not valid`); + } + + console.log(`Getting current ${commodity} price per ounce in ${currency}...`); let price = 0; + if (commodity.toLowerCase() === 'gold') { - price = 2019.80; // https://www.bullionvault.com/gold-price-chart.do - console.log(`Current gold price per ounce: ${price} USD`); - } else if (commodity.toLowerCase() === 'silver') { - price = 24.07; // https://www.bullionvault.com/silver-price-chart.do - console.log(`Current silver price per ounce: ${price} USD`); + // https://www.bullionvault.com/gold-price-chart.do + price = currency.toUpperCase() === 'USD' ? 2652.84 : 2524.52; + } else { + // https://www.bullionvault.com/silver-price-chart.do + price = currency.toUpperCase() === 'USD' ? 30.58 : 29.10; } + console.log(`Current ${commodity} price per ounce: ${price} ${currency}`); // `price` output defined in action metadata file - core.setOutput('price', price); + setOutput('price', price); // Get the JSON webhook payload for the event that triggered the workflow - const payload = JSON.stringify(github.context.payload, undefined, 2) + const payload = JSON.stringify(context.payload, undefined, 2) console.log(`The event payload: ${payload}`); } catch (error) { - core.setFailed(error.message); + setFailed(error.message); } \ No newline at end of file diff --git a/10-custom-action/readme.md b/10-custom-action/readme.md index 07a4415..f51547e 100644 --- a/10-custom-action/readme.md +++ b/10-custom-action/readme.md @@ -16,11 +16,15 @@ inputs: description: 'Commodity (gold or silver)' required: true default: 'gold' + currency: # id of input + description: 'Currency (USD or EUR)' + required: true + default: 'USD' outputs: price: # id of output description: 'The current price of the select commodity' runs: - using: 'node16' + using: 'node20' main: 'index.js' ``` @@ -33,30 +37,46 @@ npm i @actions/core @actions/github * Write the action code. Create a new file called `index.js`. ```js -const core = require('@actions/core'); -const github = require('@actions/github'); +import { getInput, setOutput, setFailed } from '@actions/core'; +import { context } from '@actions/github'; try { // `commodity` input defined in action metadata file - const commodity = core.getInput('commodity'); - console.log(`Getting current ${commodity} price per ounce...`); + const commodity = getInput('commodity'); + + // Check if input is valid + if (commodity.toLowerCase() !== 'gold' && commodity.toLowerCase() !== 'silver') { + throw new Error(`Commodity ${commodity} is not valid`); + } + + // `currency` input defined in action metadata file + const currency = getInput('currency'); + + // Check if input is valid + if (currency.toUpperCase() !== 'USD' && currency.toUpperCase() !== 'EUR') { + throw new Error(`Currency ${currency} is not valid`); + } + + console.log(`Getting current ${commodity} price per ounce in ${currency}...`); let price = 0; + if (commodity.toLowerCase() === 'gold') { - price = 2019.80; // https://www.bullionvault.com/gold-price-chart.do - console.log(`Current gold price per ounce: ${price} USD`); - } else if (commodity.toLowerCase() === 'silver') { - price = 24.07; // https://www.bullionvault.com/silver-price-chart.do - console.log(`Current silver price per ounce: ${price} USD`); + // https://www.bullionvault.com/gold-price-chart.do + price = currency.toUpperCase() === 'USD' ? 2652.84 : 2524.52; + } else { + // https://www.bullionvault.com/silver-price-chart.do + price = currency.toUpperCase() === 'USD' ? 30.58 : 29.10; } + console.log(`Current ${commodity} price per ounce: ${price} ${currency}`); // `price` output defined in action metadata file - core.setOutput('price', price); + setOutput('price', price); // Get the JSON webhook payload for the event that triggered the workflow - const payload = JSON.stringify(github.context.payload, undefined, 2) + const payload = JSON.stringify(context.payload, undefined, 2) console.log(`The event payload: ${payload}`); } catch (error) { - core.setFailed(error.message); + setFailed(error.message); } ``` @@ -66,7 +86,7 @@ try { ```bash git add action.yml index.js node_modules/* package.json package-lock.json README.md git commit -m "Action ready for release" -git tag -a -m "Get commodity price action initial release" v1.0.1 +git tag -a -m "Get commodity price action initial release" v1.0.0 git push --follow-tags ``` @@ -97,9 +117,10 @@ jobs: steps: - name: Get commodity price step - uses: jtrillo/get-commodity-price-action@v1.0.1 + uses: jtrillo/get-commodity-price-action@v1.0.0 with: - commodity: 'silver' + commodity: silver + currency: EUR ``` ```bash @@ -110,6 +131,43 @@ git push * Now we can fire the workflow and check if the custom action we have created works. +* We could also use matrix strategy to try out several combinations at the same time. + +> Some not valid values could be added in the matrix too. Custom action will throw an error. + +```diff +name: Workflow to test the custom action + +on: + workflow_dispatch: + +jobs: + get_commodity_price: + runs-on: ubuntu-latest ++ strategy: ++ matrix: ++ commodity: ["gold", "SILVER"] ++ currency: ["USD", "eur"] + + steps: + - name: Get commodity price + id: commodity_price + uses: jtrillo/get-commodity-price-action@v1.0.0 + with: +- commodity: silver ++ commodity: ${{ matrix.commodity }} +- currency: EUR ++ currency: ${{ matrix.currency }} +``` + +* Push the new changes and fire the workflow again + +```bash +git add . +git commit -m "added matrix strategy to test custom action" +git push +``` + * We can also make use of action's output in a different step. ```diff @@ -121,16 +179,21 @@ on: jobs: get_commodity_price: runs-on: ubuntu-latest + strategy: + matrix: + commodity: ["gold", "silver"] + currency: ["USD", "EUR"] steps: - name: Get commodity price step + id: commodity_price uses: jtrillo/get-commodity-price@v1.0.0 with: - commodity: 'silver' + commodity: ${{ matrix.commodity }} + currency: ${{ matrix.currency }} + # Use the output from `commodity_price` step + - name: Get the output price -+ run: echo "Price per ounce is ${{ steps.commodity_price.outputs.price }} USD" ++ run: echo "Price per ounce is ${{ steps.commodity_price.outputs.price }} ${{ matrix.currency }}" ``` * Push the new changes and fire the workflow again From 84cfab5fe7992dc2c9f74fbe280adc35fc91604b Mon Sep 17 00:00:00 2001 From: Joaquin Trillo Date: Thu, 15 Jan 2026 22:02:57 +0100 Subject: [PATCH 2/3] Update 6th edition --- .github/workflows/cd-docker.yml | 10 ++--- .github/workflows/cd-using-docker-actions.yml | 16 +++---- .github/workflows/ci.yml | 12 +++--- .github/workflows/reusable-node-build.yml | 6 +-- 01-setup-ci/readme.md | 10 ++--- 02-multiple-target-environments/readme.md | 10 ++--- 03-running-multiple-jobs/readme.md | 14 +++---- 04-working-with-build-artifacts/readme.md | 24 +++++------ 05-integration-tests/readme.md | 42 +++++++++++++++++++ 06-service-containers/readme.md | 8 ++-- 08-continous-delivery/readme.md | 16 +++---- .../01-creating-reusable-workflow/readme.md | 12 +++--- 10-custom-action/action-files/README.md | 12 +++++- 10-custom-action/readme.md | 2 +- 14 files changed, 122 insertions(+), 72 deletions(-) diff --git a/.github/workflows/cd-docker.yml b/.github/workflows/cd-docker.yml index a678220..9f6accd 100644 --- a/.github/workflows/cd-docker.yml +++ b/.github/workflows/cd-docker.yml @@ -12,8 +12,8 @@ jobs: # runs-on: ubuntu-latest # steps: - # - uses: actions/checkout@v4 - # - uses: actions/setup-node@v4 + # - uses: actions/checkout@v6 + # - uses: actions/setup-node@v6 # with: # node-version: 16 # cache: 'npm' @@ -23,7 +23,7 @@ jobs: # run: | # npm ci # npm run build --if-present - # - uses: actions/upload-artifact@v4 + # - uses: actions/upload-artifact@v6 # with: # name: build-code # path: hangman-api/dist/ @@ -33,8 +33,8 @@ jobs: needs: build steps: - - uses: actions/checkout@v4 - - uses: actions/download-artifact@v4 + - uses: actions/checkout@v6 + - uses: actions/download-artifact@v7 with: name: build-code path: hangman-api/dist/ diff --git a/.github/workflows/cd-using-docker-actions.yml b/.github/workflows/cd-using-docker-actions.yml index 67474ad..9b069d7 100644 --- a/.github/workflows/cd-using-docker-actions.yml +++ b/.github/workflows/cd-using-docker-actions.yml @@ -8,8 +8,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 with: node-version: 16 cache: 'npm' @@ -19,7 +19,7 @@ jobs: run: | npm ci npm run build --if-present - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v6 with: name: build-code path: hangman-api/dist/ @@ -29,8 +29,8 @@ jobs: # needs: build # steps: - # - uses: actions/checkout@v4 - # - uses: actions/download-artifact@v4 + # - uses: actions/checkout@v6 + # - uses: actions/download-artifact@v7 # with: # name: build-code # path: hangman-api/dist/ @@ -52,9 +52,9 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Download dist folder as artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 - name: Docker Hub login uses: docker/login-action@v3 with: @@ -64,7 +64,7 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build and push Docker Image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: ./hangman-api push: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7fa36dc..9463062 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,8 +15,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 with: node-version: 16 cache: "npm" @@ -32,8 +32,8 @@ jobs: needs: build steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 with: node-version: 16 - name: test @@ -63,8 +63,8 @@ jobs: - 5432:5432 steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 with: node-version: 16 # - name: Create database relationships diff --git a/.github/workflows/reusable-node-build.yml b/.github/workflows/reusable-node-build.yml index 93a42fa..5d67314 100644 --- a/.github/workflows/reusable-node-build.yml +++ b/.github/workflows/reusable-node-build.yml @@ -15,8 +15,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 with: node-version: ${{ inputs.node-version }} cache: "npm" @@ -26,7 +26,7 @@ jobs: run: | npm ci npm run build --if-present - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v6 with: name: build-code path: ${{ inputs.working-directory }}/dist/ diff --git a/01-setup-ci/readme.md b/01-setup-ci/readme.md index 84de6c2..9677bf5 100644 --- a/01-setup-ci/readme.md +++ b/01-setup-ci/readme.md @@ -82,7 +82,7 @@ jobs: steps: + - name: Checkout # This field is optional -+ - uses: actions/checkout@v4 ++ - uses: actions/checkout@v6 - name: inspect run: | ls -al @@ -92,7 +92,7 @@ jobs: ``` -Recall that on job steps we can use an action or run a command. Here we're using an action `actions/checkout@v4` that needs no further configuration. +Recall that on job steps we can use an action or run a command. Here we're using an action `actions/checkout@v6` that needs no further configuration. ```bash git add . @@ -140,7 +140,7 @@ jobs: - runs-on: ubuntu-latest - steps: -- - uses: actions/checkout@v4 +- - uses: actions/checkout@v6 - - name: inspect - run: | - ls -al @@ -164,7 +164,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: build and test working-directory: ./hangman-api run: | @@ -201,7 +201,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: build and test working-directory: ./hangman-api run: | diff --git a/02-multiple-target-environments/readme.md b/02-multiple-target-environments/readme.md index 5304ee0..b9b3bd6 100644 --- a/02-multiple-target-environments/readme.md +++ b/02-multiple-target-environments/readme.md @@ -38,7 +38,7 @@ jobs: node-version: [16, 17, 18] # diff # steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: build and test working-directory: ./hangman-api run: | @@ -60,10 +60,10 @@ jobs: node-version: [16, 17, 18] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 # diff # - name: Setup Node.js environment - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} # diff # @@ -132,9 +132,9 @@ jobs: + os: [ubuntu-20.04, ubuntu-22.04] + runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js environment - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} - name: build and test diff --git a/03-running-multiple-jobs/readme.md b/03-running-multiple-jobs/readme.md index c5fad36..7365b83 100644 --- a/03-running-multiple-jobs/readme.md +++ b/03-running-multiple-jobs/readme.md @@ -44,9 +44,9 @@ jobs: - runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - - name: Setup Node.js environment -- uses: actions/setup-node@v4 +- uses: actions/setup-node@v6 - with: - node-version: ${{ matrix.node-version }} - name: build and test @@ -68,7 +68,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - - name: build and test + - name: build working-directory: ./hangman-api @@ -98,7 +98,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: build working-directory: ./hangman-api run: | @@ -109,7 +109,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: test working-directory: ./hangman-api run: | @@ -188,7 +188,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: build working-directory: ./hangman-api run: | @@ -199,7 +199,7 @@ jobs: runs-on: ubuntu-latest + needs: build # If it depends on more than one, use an array steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: test working-directory: ./hangman-api run: | diff --git a/04-working-with-build-artifacts/readme.md b/04-working-with-build-artifacts/readme.md index 0020631..afd51cd 100644 --- a/04-working-with-build-artifacts/readme.md +++ b/04-working-with-build-artifacts/readme.md @@ -40,14 +40,14 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: build working-directory: ./hangman-api run: | npm ci npm run build --if-present # diff # - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v6 with: name: dependencies path: hangman-api/node_modules/ @@ -67,13 +67,13 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: build working-directory: ./hangman-api run: | npm ci npm run build --if-present - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v6 with: name: dependencies path: hangman-api/node_modules/ @@ -84,9 +84,9 @@ jobs: needs: build steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 # diff - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v7 with: name: dependencies path: hangman-api/node_modules @@ -123,8 +123,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 -+ - uses: actions/setup-node@v4 + - uses: actions/checkout@v6 ++ - uses: actions/setup-node@v6 + with: + node-version: 16 + cache: 'npm' @@ -134,7 +134,7 @@ jobs: run: | npm ci npm run build --if-present -- - uses: actions/upload-artifact@v4 +- - uses: actions/upload-artifact@v6 - with: - name: dependencies - path: hangman-api/node_modules/ @@ -145,13 +145,13 @@ jobs: needs: build steps: - - uses: actions/checkout@v4 -- - uses: actions/download-artifact@v4 + - uses: actions/checkout@v6 +- - uses: actions/download-artifact@v7 - with: - name: dependencies - path: hangman-api/node_modules - include-hidden-files: true -+ - uses: actions/setup-node@v4 ++ - uses: actions/setup-node@v6 + with: + node-version: 16 - name: test diff --git a/05-integration-tests/readme.md b/05-integration-tests/readme.md index aa834ec..7a75ce1 100644 --- a/05-integration-tests/readme.md +++ b/05-integration-tests/readme.md @@ -254,3 +254,45 @@ Ran all test suites. ``` > Exercise: Update CI pipeline to run test integration using docker compose. + +```yaml +test-integration: + runs-on: ubuntu-latest + needs: test + + services: + postgres: + image: postgres:14-alpine + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: hangman_db + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Setup Node version + uses: actions/setup-node@v6 + with: + node-version: 20 + - name: Running integration test + working-directory: ./hangman-api + env: + DATABASE_PORT: 5432 + DATABASE_HOST: localhost + DATABASE_NAME: hangman_db + DATABASE_USER: postgres + DATABASE_PASSWORD: postgres + DATABASE_POOL_MIN: 2 + DATABASE_POOL_MAX: 10 + run: | + npm ci + npx knex migrate:latest --env development + npm run test:integration +``` diff --git a/06-service-containers/readme.md b/06-service-containers/readme.md index b5c99db..82f9484 100644 --- a/06-service-containers/readme.md +++ b/06-service-containers/readme.md @@ -44,8 +44,8 @@ Now, before running the integration tests, we need to setup the schemas: ```yml steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 with: node-version: 16 - name: Create database relationships @@ -85,8 +85,8 @@ Ok let's rename and add the instructions to run our integration tests: ```diff steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 with: node-version: 16 - - name: Create database relationships diff --git a/08-continous-delivery/readme.md b/08-continous-delivery/readme.md index 3bd7180..446657c 100644 --- a/08-continous-delivery/readme.md +++ b/08-continous-delivery/readme.md @@ -133,8 +133,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 with: node-version: 16 cache: 'npm' @@ -144,7 +144,7 @@ jobs: run: | npm ci npm run build --if-present - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v6 with: name: build-code path: hangman-api/dist/ @@ -160,8 +160,8 @@ Now we need to build the image before push it to Docker registry we can do this needs: build steps: - - uses: actions/checkout@v4 - - uses: actions/download-artifact@v4 + - uses: actions/checkout@v6 + - uses: actions/download-artifact@v7 with: name: build-code path: hangman-api/dist/ @@ -247,9 +247,9 @@ Let's update `delivery` job: steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Download dist folder as artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v7 - name: Docker Hub login uses: docker/login-action@v3 with: @@ -259,7 +259,7 @@ Let's update `delivery` job: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build and push Docker Image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: ./hangman-api push: true diff --git a/09-workflow-calls/01-creating-reusable-workflow/readme.md b/09-workflow-calls/01-creating-reusable-workflow/readme.md index 0389cb1..7d103ec 100644 --- a/09-workflow-calls/01-creating-reusable-workflow/readme.md +++ b/09-workflow-calls/01-creating-reusable-workflow/readme.md @@ -29,8 +29,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 with: node-version: ${{ inputs.node-version }} cache: 'npm' @@ -40,7 +40,7 @@ jobs: run: | npm ci npm run build --if-present - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v6 with: name: build-code path: ${{ inputs.working-directory }}/dist/ @@ -64,8 +64,8 @@ jobs: - runs-on: ubuntu-latest - steps: -- - uses: actions/checkout@v4 -- - uses: actions/setup-node@v4 +- - uses: actions/checkout@v6 +- - uses: actions/setup-node@v6 - with: - node-version: 16 - cache: 'npm' @@ -75,7 +75,7 @@ jobs: - run: | - npm ci - npm run build --if-present -- - uses: actions/upload-artifact@v4 +- - uses: actions/upload-artifact@v6 - with: - name: build-code - path: hangman-api/dist/ diff --git a/10-custom-action/action-files/README.md b/10-custom-action/action-files/README.md index 26c2cc1..5031c85 100644 --- a/10-custom-action/action-files/README.md +++ b/10-custom-action/action-files/README.md @@ -6,7 +6,15 @@ This action prints current price per ounce for the selected commodity. ### `commodity` -**Required** The commodity you want to know its current price per ounce. Default `"gold"`. +- **Required**. The commodity you want to know its current price per ounce. +- Possible values: `gold` and `silver`. +- Default value: `gold`. + +### `currency` + +- **Required**. The desired currency. +- Possible values: `USD` and `EUR`. +- Default value: `USD`. ## Outputs @@ -17,7 +25,7 @@ The current price for the selected commodity. ## Example usage ```yaml -uses: jtrillo/get-commodity-price-action@v1 +uses: jtrillo/get-commodity-price-action@v1.0.0 with: commodity: 'silver' ``` diff --git a/10-custom-action/readme.md b/10-custom-action/readme.md index f51547e..5ee0d48 100644 --- a/10-custom-action/readme.md +++ b/10-custom-action/readme.md @@ -5,7 +5,7 @@ In this last demo we will create a custom action and use it in a workflow. ## Steps * Create a new **public** repository on GitHub and call it *get-commodity-price-action*. Clone it to your computer and open this repo in your editor. -* Create a new Node.js project using `npm init -y`. +* Create a new Node.js project using `npm init -y`. Change type to `module` in `package.json`: `"type": "module"` * Create the action metadata file. It should be named `action.yml`. ```yaml From 9bfb14ad3cad2748844464bd5743a3be034b3dc1 Mon Sep 17 00:00:00 2001 From: Joaquin Trillo Date: Thu, 15 Jan 2026 22:16:29 +0100 Subject: [PATCH 3/3] fixing typos --- 04-working-with-build-artifacts/readme.md | 2 +- 09-workflow-calls/readme.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/04-working-with-build-artifacts/readme.md b/04-working-with-build-artifacts/readme.md index afd51cd..e7ab0a7 100644 --- a/04-working-with-build-artifacts/readme.md +++ b/04-working-with-build-artifacts/readme.md @@ -109,7 +109,7 @@ git push And trigger the workflow from project site. -**DEPRECATED.** ~~If we check the workflow, we will notice that is taking a long time to resolve the dependencies upload~~. **Both actions in version 4 improve significatly the performance. Check this article: **. +**DEPRECATED.** ~~If we check the workflow, we will notice that is taking a long time to resolve the dependencies upload~~. **Both actions in version 4 improve significantly the performance. Check this article: **. However, this approach is not the proper way to manage this, let's try something different: using the cache. diff --git a/09-workflow-calls/readme.md b/09-workflow-calls/readme.md index 331ae2e..2a1a79c 100644 --- a/09-workflow-calls/readme.md +++ b/09-workflow-calls/readme.md @@ -31,8 +31,8 @@ After you add a `workflow_call` trigger, you need to make sure that your reposit There are [limitations](https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations). Some of them are: * **You can't reference a reusable workflow that's in a private repository**. If you have a reusable workflow in a private repository, only other workflows in that private repository can use it. -* **Reusable workflows cant be stacked on top of one another, but there is a limit**. You can connect a maximum of four levels of workflows - that is, the top-level caller workflow and up to three levels of reusable workflows. For example: caller-workflow.yml → called-workflow-1.yml → called-workflow-2.yml → called-workflow-3.yml. Loops in the workflow tree are not permitted. More info [here](https://docs.github.com/en/actions/sharing-automations/reusing-workflows#nesting-reusable-workflows) -* **You can call a maximum of 20 unique reusable workflows from a single worklow file**. This limit includes nested/stacked reusable workflows. +* **Reusable workflows can't be stacked on top of one another, but there is a limit**. You can connect a maximum of four levels of workflows - that is, the top-level caller workflow and up to three levels of reusable workflows. For example: caller-workflow.yml → called-workflow-1.yml → called-workflow-2.yml → called-workflow-3.yml. Loops in the workflow tree are not permitted. More info [here](https://docs.github.com/en/actions/sharing-automations/reusing-workflows#nesting-reusable-workflows) +* **You can call a maximum of 20 unique reusable workflows from a single workflow file**. This limit includes nested/stacked reusable workflows. ## Reusable workflows vs composite actions