Actions Customizadas
Aula 2 de 5
Tipos de Actions
Docker container: ambiente completo, lento mas consistente
JavaScript/TypeScript: rápido (node), sem dependências
Composite: combinação de steps (DRY)
Action JavaScript
# action.yml
name: 'Slack Notification'
description: 'Envia notificação para Slack'
inputs:
message:
description: 'Mensagem a enviar'
required: true
webhook-url:
description: 'Slack webhook URL'
required: true
outputs:
timestamp:
description: 'Timestamp do envio'
value: ${{ steps.send.outputs.time }}
runs:
using: 'node20'
main: 'dist/index.js'
// index.js
const core = require('@actions/core');
const fetch = require('node-fetch');
async function run() {
try {
const message = core.getInput('message');
const webhook = core.getInput('webhook-url');
const resp = await fetch(webhook, {
method: 'POST',
body: JSON.stringify({ text: message }),
});
core.setOutput('timestamp', new Date().toISOString());
core.info(`Notificação enviada: ${message}`);
} catch (error) {
core.setFailed(error.message);
}
}
run();
# Build para distribuição
npm install @actions/core node-fetch
npx ncc build index.js --license licenses.txt
Action Docker
# action.yml
name: 'Lint with ShellCheck'
description: 'Check shell scripts'
inputs:
path:
description: 'Path to scan'
default: '.'
runs:
using: 'docker'
image: 'Dockerfile'
args:
- ${{ inputs.path }}
FROM koalaman/shellcheck-alpine:stable
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
Composite Action
# actions/setup-node-cache/action.yml
name: 'Setup Node with Cache'
description: 'Node + pnpm cache'
inputs:
node-version:
default: '20'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- uses: pnpm/action-setup@v3
with:
version: latest
- uses: actions/cache@v4
id: pnpm-cache
with:
path: ~/.pnpm-store
key: ${{ runner.os }}-pnpm-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-
- if: steps.pnpm-cache.outputs.cache-hit != 'true'
run: pnpm install
shell: bash
Reusable Workflows
# .github/workflows/deploy-template.yml (chamado)
on:
workflow_call:
inputs:
environment:
required: true
type: string
secrets:
cloud-token:
required: true
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
steps:
- uses: actions/checkout@v4
- run: echo "Deploying to ${{ inputs.environment }}"
# .github/workflows/deploy-prod.yml (chamador)
on:
push:
branches: [main]
jobs:
call-deploy:
uses: ./.github/workflows/deploy-template.yml
with:
environment: production
secrets:
cloud-token: ${{ secrets.CLOUD_TOKEN }}
Publicar no Marketplace
# Estrutura recomendada
your-action/
├── action.yml
├── dist/
│ └── index.js
├── src/
│ └── index.ts
├── package.json
├── tsconfig.json
├── LICENSE
└── README.md
# action.yml (com branding)
branding:
icon: 'bell'
color: 'yellow'
Actions são blocos reutilizáveis. Composite actions são ideais para combinar steps complexos. Reusable workflows evitam duplicação entre repos. Use @actions/core para boilerplate.