Workflows With GitHub Actions
La idea es construir nuestro workflow con GitHub Actions desde lo más simple hasta agregarle un poco de complejidad.
- One Job
- Secrets
- Deploy
- Multiple Jobs with artifacts
- Conditioned Jobs And Environments
Para hacer esto un poco más realista, todo el flujo se basará sobre una app con react, pero se puede aplicar a cualquier tipo de código.
One Job
.github/worflows/main.yml
name: workflow with github actions
'on':
push:
branches:
- one-job
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14'
- name: install
run: npm install
- name: test
run: npm run test
- name: build
run: npm run build
una de las cosas importantes aquí es definir una versión de node sobre la cual trabajar, por eso usamos actions/setup-node@v2 definiendo nuestra versión como 14, después procedemos a instalar las dependencias, hacer build y ejecutar las pruebas.
Actions secrets
Antes de entrar en temas de deploy debemos saber definir y llamar a nuestras secrets, para definirlas vamos a settings / secrets y damos click en new repository secret
name: TOKEN
value: FIREBASE TOKEN
Agregamos la secret, en este caso voy a hacer un deploy a Firebase hosting, por eso agrego el token .
Para acceder a la secret hacemos
${{ secrets.TOKEN }}
Deploy
Para hacer el deploy basta con agregar otro step a nuestro job que instale el cli de firebase y haga el deploy.
- name: deploy
run: |
npm install -g firebase-tools
firebase deploy --token ${{ secrets.TOKEN }}
main.yml
name: workflow with github actions
'on':
push:
branches:
- one-job
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14'
- name: install
run: npm install
- name: test
run: npm run test
- name: build
run: npm run build
- name: deploy
run: |
npm install -g firebase-tools
firebase deploy --token ${{ secrets.TOKEN }}
Listo, tenemos nuestro flujo de un solo job.
Multiple Jobs
La idea es hacer separar todo el flujo en diferentes jobs
jobs:
install_and_test:
runs-on: ubuntu-latest
steps:
- name: install and test
run: echo "install and test"
build:
needs:
- install_and_test
runs-on: ubuntu-latest
steps:
- name: build
run: echo "build"
deploy:
needs:
- build
runs-on: ubuntu-latest
steps:
- name: deploy
run: echo "deploy"
Aquí tenemos el esqueleto, install and test, build, deploy.
Por medio de needs definimos cuáles jobs son necesario para que otros se ejecuten, con esto rompemos el flujo natural que es en paralelo.
Artifacts
Son datos que se comparten entre jobs, uno de ellos lo sube y los otros pueden descargarlo cuando estén ejecutándose.
install_and_test
jobs:
install_and_test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14'
cache: "npm"
- run: npm install
- run: npm test
lo único nuevo es el cache al momento de seleccionar la versión de node, esto nos permite ahorrar algo tiempo al momento de instalar las dependencias en los diferentes jobs
build
build:
needs:
- install_and_test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14'
cache: npm
- run: npm install
- run: npm run build
- run: rm -r node_modules
- name: artifact
uses: actions/upload-artifact@v2
with:
name: app
path: .
Procedemos a instalar las dependencias, hacer build y borrar la carpeta node_modules, después subimos nuestro codigo como artifact bajo el nombre app.
deploy
deploy:
needs:
- build
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v2
with:
node-version: '14'
- uses: actions/download-artifact@v2
with:
name: app
- name: install firebase cli
run: npm install -g firebase-tools
- name: deploy
run: firebase deploy --token ${{ secrets.TOKEN }}
En el job deploy bajamos el artifact, instalamos firebase cli y hacemos deploy.
main.yml
name: workflow with github actions
on:
push:
branches:
- main
- dev
- multiples-jobs
jobs:
install_and_test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: "14"
cache: "npm"
- run: npm install
- run: npm test build:
needs: [install_and_test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: "14"
cache: "npm"
- run: npm install
- run: npm run build
- run: rm -r node_modules
- name: artifact
uses: actions/upload-artifact@v2
with:
name: app
path: . deploy:
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v2
with:
node-version: "14"
- uses: actions/download-artifact@v2
with:
name: app
- name: install firebase cli
run: npm install -g firebase-tools
- name: deploy
run: firebase deploy --token ${{ secrets.TOKEN }}
Conditioned Jobs And Environments
Environments
la idea es cambiar el valor de nuestro secrets TOKEN dependiendo si queremos hacer deploy a dev o prod, para esto vamos a la configuración de nuestro repositorio en github y entramos en environments,.
Creamos un nuevo environment de nombre DEV y otro de nombre PROD, podemos agregarle una regla que indique que solo ciertas branches tengan acceso al enviroment, añadimos nuestro secret TOKEN (importante conservar el mismo nombre).
Hacemos el mismo proceso para PROD
listo, tenemos nuestros environments configurados, ahora hagamos los cambios en el main.yml
lo primero es agregar dos jobs que dependan de build, tengan como condicional su rama de referencia y su environment seleccionado
deploy_dev
deploy_dev:
if: ${{ github.ref == 'refs/heads/dev' }}
environment: DEV
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v2
with:
node-version: "14"
- uses: actions/download-artifact@v2
with:
name: app
- name: install firebase cli
run: npm install -g firebase-tools
- name: deploy
run: echo "deploy to dev"
Para el ejemplo no tengo donde hacer deploy para dev por lo que solo imprimo un mensaje.
deploy_prod
deploy_prod:
if: ${{ github.ref == 'refs/heads/main' }}
environment: PROD
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v2
with:
node-version: "14"
- uses: actions/download-artifact@v2
with:
name: app
- name: install firebase cli
run: npm install -g firebase-tools
- name: deploy
run: firebase deploy --token ${{ secrets.TOKEN }}
listo, esto en Github Actions se observa la siguiente forma
main.yml
name: workflow with github actions
on:
push:
branches:
- main
- dev
jobs:
install_and_test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: "14"
cache: "npm"
- run: npm install
- run: npm test build:
needs: [install_and_test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: "14"
cache: "npm"
- run: npm install
- run: npm run build
- run: rm -r node_modules
- name: artifact
uses: actions/upload-artifact@v2
with:
name: app
path: . deploy_dev:
if: ${{ github.ref == 'refs/heads/dev' }}
environment: DEV
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v2
with:
node-version: "14"
- uses: actions/download-artifact@v2
with:
name: app
- name: install firebase cli
run: npm install -g firebase-tools
- name: deploy
run: echo "deploy to dev" deploy_prod:
if: ${{ github.ref == 'refs/heads/main' }}
environment: PROD
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v2
with:
node-version: "14"
- uses: actions/download-artifact@v2
with:
name: app
- name: install firebase cli
run: npm install -g firebase-tools
- name: deploy
run: firebase deploy --token ${{ secrets.TOKEN }}
Si usas vscode te recomiendo la extensión Github Actions, te permite ver las acciones, los secrets y environments desde el editor.