Pular para o conteúdo

Deploy via CI/CD

Esta página descreve o fluxo recomendado para publicar automações com a CLI em pipelines como GitHub Actions, GitLab CI e Jenkins, sem usar tunnelhub login.

O modelo recomendado usa credenciais CI/CD account-level com allowlist de ambientes. A credencial pertence à conta, mas só pode fazer deploy nos UUIDs de ambiente autorizados durante a criação.

Antes de configurar o pipeline, você precisa:

  • ter uma automação já criada no TunnelHub;
  • ter o tunnelhub.yml configurado com a automação que será publicada;
  • saber o UUID de cada ambiente TunnelHub que o pipeline poderá publicar;
  • ter permissão para acessar Administration > Settings;
  • se for usar GitHub Actions, ter permissão para criar GitHub Environments, secrets e variables no repositório.

No portal do TunnelHub:

  1. acesse Administration > Settings;
  2. abra a aba CI/CD;
  3. clique em Criar credencial CI/CD;
  4. informe um nome para a credencial;
  5. selecione os ambientes autorizados para a credencial;
  6. conclua a criação;
  7. copie o Client ID e o Client secret exibidos.

Observações importantes:

  • a credencial é da account, mas só pode fazer deploy nos ambientes autorizados na criação;
  • você pode liberar ambientes específicos ou usar a opção de todos os ambientes;
  • o Client secret é exibido apenas uma vez;
  • se o secret for perdido ou exposto, use Regenerar secret ou Revogar;
  • para produção, prefira credenciais separadas por ambiente para reduzir blast radius.

No GitHub Actions, a separação recomendada é:

  • TH_CLIENT_ID: GitHub Environment Secret;
  • TH_CLIENT_SECRET: GitHub Environment Secret;
  • TH_ENVIRONMENT_ID: GitHub Environment Variable;
  • TH_API_HOST: repositório variable, GitHub Environment Variable ou valor fixo no workflow.

Exemplo de valores:

  • TH_API_HOST: https://api.tunnelhub.io
  • TH_ENVIRONMENT_ID: UUID de um ambiente TunnelHub autorizado para essa credencial

A automação publicada é inferida automaticamente a partir do tunnelhub.yml do projeto.

Se você usar outra plataforma de CI/CD, mantenha a mesma ideia:

  • TH_CLIENT_ID e TH_CLIENT_SECRET como secrets;
  • TH_ENVIRONMENT_ID como variável por ambiente;
  • TH_API_HOST como variável ou valor fixo do pipeline.

3. Entenda GitHub Environment vs TunnelHub Environment

Seção intitulada “3. Entenda GitHub Environment vs TunnelHub Environment”

Esses dois conceitos são diferentes:

  • GitHub Environment: controla approvals, protection rules, secrets e variables dentro do GitHub;
  • TunnelHub Environment: é o UUID passado para --environment-id no deploy.

O vínculo entre os dois acontece pela variável TH_ENVIRONMENT_ID.

Exemplo:

  • GitHub Environment production pode ter TH_ENVIRONMENT_ID=<uuid-do-ambiente-production-no-tunnelhub>;
  • GitHub Environment development pode ter TH_ENVIRONMENT_ID=<uuid-do-ambiente-development-no-tunnelhub>.

O deploy CI/CD usa a mesma CLI pública, mas autenticada com variáveis de ambiente M2M.

O parâmetro --message é obrigatório e deve carregar o contexto humano do deploy.

Os exemplos abaixo usam a mensagem completa do último commit e o e-mail do autor para preencher --message.

Antes de executar deploy-automation, o workflow precisa gerar o artefato ZIP configurado em package.artifact no tunnelhub.yml. Os exemplos abaixo usam corepack e detectam pnpm, yarn ou npm pelo lockfile do projeto. Ajuste os comandos se o seu repositório usar outro fluxo de build.

Use este exemplo quando apenas a branch main deve publicar, mapeada para o GitHub Environment production.

name: Deploy TunnelHub Automation
on:
push:
branches:
- main
workflow_dispatch:
jobs:
deploy-production:
if: github.ref_name == 'main'
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- name: Enable Corepack
run: corepack enable
- name: Install dependencies
run: |
if [ -f pnpm-lock.yaml ]; then
pnpm install --frozen-lockfile
elif [ -f yarn.lock ]; then
yarn install --immutable
else
npm ci
fi
- name: Build deployment artifact
run: |
if [ -f pnpm-lock.yaml ]; then
pnpm build
elif [ -f yarn.lock ]; then
yarn build
else
npm run build
fi
- name: Install TunnelHub CLI
run: npm install --global @tunnelhub/cli
- name: Deploy automation
env:
TH_API_HOST: https://api.tunnelhub.io
TH_CLIENT_ID: ${{ secrets.TH_CLIENT_ID }}
TH_CLIENT_SECRET: ${{ secrets.TH_CLIENT_SECRET }}
TH_ENVIRONMENT_ID: ${{ vars.TH_ENVIRONMENT_ID }}
run: |
COMMIT_EMAIL="$(git log -1 --pretty=format:'%ae')"
COMMIT_MESSAGE="$(git log -1 --pretty=format:'%B')"
COMMIT_SHA="$(git rev-parse --short HEAD)"
DEPLOY_MESSAGE="${COMMIT_MESSAGE}
Deploy ${COMMIT_SHA} by ${COMMIT_EMAIL}"
tunnelhub deploy-automation \
--environment-id "$TH_ENVIRONMENT_ID" \
--message "$DEPLOY_MESSAGE"

Exemplo 2: develop publica em development e main publica em production

Seção intitulada “Exemplo 2: develop publica em development e main publica em production”

Use este exemplo quando você quer separar ambientes por branch.

name: Deploy TunnelHub Automation
on:
push:
branches:
- develop
- main
workflow_dispatch:
jobs:
deploy-development:
if: github.ref_name == 'develop'
runs-on: ubuntu-latest
environment: development
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- name: Enable Corepack
run: corepack enable
- name: Install dependencies
run: |
if [ -f pnpm-lock.yaml ]; then
pnpm install --frozen-lockfile
elif [ -f yarn.lock ]; then
yarn install --immutable
else
npm ci
fi
- name: Build deployment artifact
run: |
if [ -f pnpm-lock.yaml ]; then
pnpm build
elif [ -f yarn.lock ]; then
yarn build
else
npm run build
fi
- name: Install TunnelHub CLI
run: npm install --global @tunnelhub/cli
- name: Deploy automation
env:
TH_API_HOST: https://api.tunnelhub.io
TH_CLIENT_ID: ${{ secrets.TH_CLIENT_ID }}
TH_CLIENT_SECRET: ${{ secrets.TH_CLIENT_SECRET }}
TH_ENVIRONMENT_ID: ${{ vars.TH_ENVIRONMENT_ID }}
run: |
COMMIT_EMAIL="$(git log -1 --pretty=format:'%ae')"
COMMIT_MESSAGE="$(git log -1 --pretty=format:'%B')"
COMMIT_SHA="$(git rev-parse --short HEAD)"
DEPLOY_MESSAGE="${COMMIT_MESSAGE}
Deploy ${COMMIT_SHA} by ${COMMIT_EMAIL}"
tunnelhub deploy-automation \
--environment-id "$TH_ENVIRONMENT_ID" \
--message "$DEPLOY_MESSAGE"
deploy-production:
if: github.ref_name == 'main'
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- name: Enable Corepack
run: corepack enable
- name: Install dependencies
run: |
if [ -f pnpm-lock.yaml ]; then
pnpm install --frozen-lockfile
elif [ -f yarn.lock ]; then
yarn install --immutable
else
npm ci
fi
- name: Build deployment artifact
run: |
if [ -f pnpm-lock.yaml ]; then
pnpm build
elif [ -f yarn.lock ]; then
yarn build
else
npm run build
fi
- name: Install TunnelHub CLI
run: npm install --global @tunnelhub/cli
- name: Deploy automation
env:
TH_API_HOST: https://api.tunnelhub.io
TH_CLIENT_ID: ${{ secrets.TH_CLIENT_ID }}
TH_CLIENT_SECRET: ${{ secrets.TH_CLIENT_SECRET }}
TH_ENVIRONMENT_ID: ${{ vars.TH_ENVIRONMENT_ID }}
run: |
COMMIT_EMAIL="$(git log -1 --pretty=format:'%ae')"
COMMIT_MESSAGE="$(git log -1 --pretty=format:'%B')"
COMMIT_SHA="$(git rev-parse --short HEAD)"
DEPLOY_MESSAGE="${COMMIT_MESSAGE}
Deploy ${COMMIT_SHA} by ${COMMIT_EMAIL}"
tunnelhub deploy-automation \
--environment-id "$TH_ENVIRONMENT_ID" \
--message "$DEPLOY_MESSAGE"

O deploy deve informar --environment-id ou --env com UUID. O backend valida se esse ambiente está na allowlist da credencial.

No deploy via CI/CD, a revisão criada guarda dois tipos de informação:

  • createdBy: identifica a credencial técnica que autorizou o deploy;
  • message: registra o contexto humano e operacional do deploy.

Na prática:

  • createdBy fica como api-client:<clientId>;
  • message deve conter dados como a mensagem do commit, SHA, e-mail do autor, identificador da execução ou o nome do workflow quando isso fizer sentido.

Esse desenho preserva auditoria técnica sem perder rastreabilidade humana.

Na mesma aba Administration > Settings > CI/CD, você pode:

  • usar Regenerar secret para emitir um novo secret para a credencial existente;
  • usar Revogar para bloquear novos deploys com essa credencial.

Após regenerar o secret, atualize imediatamente os secrets do pipeline.

Se você usa GitHub Environments separados, atualize cada environment que depende dessa credencial.

Se migrar para credenciais separadas por ambiente, revogue as credenciais antigas assim que o novo fluxo estiver validado.