Custom Actions são ações personalizadas no GitHub Actions que permitem estender e reutilizar funcionalidades dentro dos workflows. Você pode utilizar ações criadas por outros desenvolvedores ou criar suas próprias para atender necessidades específicas do seu projeto.

Por exemplo, para automação de builds de jogos, existe o GameCI, uma coleção de Custom Actions feitas para facilitar a integração do Unity com o GitHub Actions.


Diferentes tipos de Actions personalizados


Composite Actions

name: Deployment
on:  
	push:    
		branches:      
				- main
jobs:  
	lint:    
		runs-on: ubuntu-latest    
		steps:      
			- name: Get code        
				uses: actions/checkout@v3      
			- name: Cache dependencies        
				id: cache        
				uses: actions/cache@v3        
				with:          
					path: node_modules          
					key: deps-node-modules-${{ hashFiles('**/package-lock.json') }}      
			- name: Install dependencies        
				if: steps.cache.outputs.cache-hit != 'true'        
				run: npm ci      
			- name: Lint code        
				run: npm run lint  
	test:    
		runs-on: ubuntu-latest    
		steps:      
			- name: Get code        
				uses: actions/checkout@v3      
			- name: Cache dependencies        
				id: cache        
				uses: actions/cache@v3        
				with:          
					path: node_modules          
					key: deps-node-modules-${{ hashFiles('**/package-lock.json') }}      
			- name: Install dependencies        
				if: steps.cache.outputs.cache-hit != 'true'        
				run: npm ci      
			- name: Test code        
				id: run-tests        
				run: npm run test      
			- name: Upload test report        
				if: failure() && steps.run-tests.outcome == 'failure'        
				uses: actions/upload-artifact@v3        
				with:          
					name: test-report          
					path: test.json  
	build:    
		needs: test    
		runs-on: ubuntu-latest    
		steps:      
			- name: Get code        
				uses: actions/checkout@v3      
			- name: Cache dependencies        
				id: cache        
				uses: actions/cache@v3        
				with:          
					path: node_modules          
					key: deps-node-modules-${{ hashFiles('**/package-lock.json') }}      
			- name: Install dependencies        
				if: steps.cache.outputs.cache-hit != 'true'        
				run: npm ci      
			- name: Build website        
				run: npm run build      
			- name: Upload artifacts        
				uses: actions/upload-artifact@v3        
				with:          
					name: dist-files          
					path: dist  
	deploy:    
		needs: build    
		runs-on: ubuntu-latest    
		steps:      
			- name: Get code        
				uses: actions/checkout@v3      
			- name: Get build artifacts        
				uses: actions/download-artifact@v3        
				with:          
					name: dist-files          
					path: ./dist      
			- name: Output contents        
				run: ls      
			- name: Deploy site        
				run: echo "Deploying..."

Como visto no workflow acima, baixar dependencias e fazer o cache é um processo que se repete algumas vezes. Para evitar isso, usaremos o composite.

Primeiro, criei dentro da basta .github uma pasta chamada “actions” e, dentro do actions, criei mais uma chamada “cached-deps” para colocar o arquivo do step que faz o caching.

image.png

Dentro do action.yml será onde o ação será configurada.

name: 'Get and Cache Dependencies'
description: 'Get the dependencies via npm and Cache them'
runs:  
	using: 'composite'  
	steps:      
	- name: Cache dependencies        
		id: cache        
		uses: actions/cache@v3        
		with:          
			path: node_modules          
			key: deps-node-modules-${{ hashFiles('**/package-lock.json') }}      
	- name: Install dependencies        
		if: steps.cache.outputs.cache-hit != 'true'        
		run: npm ci        
		shell: bash

Sempre que o step envolver linhas de comando, é preciso adicionar o “shell”, onde ele será rodado.

E para usar isso no workflow é muito simples:

name: Deployment
on:  
	push:    
		branches:      
				- main
jobs:  
	lint:    
		runs-on: ubuntu-latest    
		steps:      
			- name: Get code        
				uses: actions/checkout@v3      
      - name: Load and Cache dependencies        
				uses: ./.github/actions/cached-deps
			- name: Lint code        
				run: npm run lint  
	test:    
		runs-on: ubuntu-latest    
		steps:      
			- name: Get code        
				uses: actions/checkout@v3      
			- name: Load and Cache dependencies        
				uses: ./.github/actions/cached-deps
			- name: Test code        
				id: run-tests        
				run: npm run test      
			- name: Upload test report        
				if: failure() && steps.run-tests.outcome == 'failure'        
				uses: actions/upload-artifact@v3        
				with:          
					name: test-report          
					path: test.json  
	build:    
		needs: test    
		runs-on: ubuntu-latest    
		steps:      
			- name: Get code        
				uses: actions/checkout@v3      
      - name: Load and Cache dependencies        
				uses: ./.github/actions/cached-deps
			- name: Build website        
				run: npm run build      
			- name: Upload artifacts        
				uses: actions/upload-artifact@v3        
				with:          
					name: dist-files          
					path: dist  
	deploy:    
		needs: build    
		runs-on: ubuntu-latest    
		steps:      
			- name: Get code        
				uses: actions/checkout@v3      
			- name: Get build artifacts        
				uses: actions/download-artifact@v3        
				with:          
					name: dist-files          
					path: ./dist      
			- name: Output contents        
				run: ls      
			- name: Deploy site        
				run: echo "Deploying..."

Veja que por eu ter criado em um arquivo local, eu referenciei a pasta. Mas caso você crie em um repositório e queira usar em outro, basta referenciar o repositório original.

Inputs no composite