Public Access
fa0b5b7865
- Add GA_TOKEN to token fallback chain across all 25 workflow templates
(secrets.GA_TOKEN || secrets.GH_TOKEN || github.token)
- Replace hardcoded MokoStandards clone URLs with platform-detecting
MOKO_CLONE_TOKEN/MOKO_CLONE_HOST env vars in 11 templates
- Replace actions/github-script@v7 with shell-based API calls in
repo_health (Joomla + Dolibarr) and validate-joomla-project
- Replace hardcoded ApiClient('api.github.com') with PlatformAdapterFactory
in health-check.yml and integration-tests.yml
- Add TODO markers for terraform github-script blocks (complex logic)
- Update publish-to-mokodolimods token references
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
211 lines
7.5 KiB
Plaintext
211 lines
7.5 KiB
Plaintext
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
#
|
|
# This file is part of a Moko Consulting project.
|
|
#
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
#
|
|
# FILE INFORMATION
|
|
# DEFGROUP: Gitea.Workflow
|
|
# INGROUP: MokoStandards.Terraform
|
|
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards-API
|
|
# PATH: /templates/workflows/terraform/deploy.yml.template
|
|
# VERSION: 04.06.00
|
|
# BRIEF: Terraform infrastructure deployment workflow for multiple environments
|
|
# NOTE: Applies Terraform configurations to provision and manage infrastructure
|
|
|
|
name: Terraform Deploy
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
environment:
|
|
description: 'Environment to deploy'
|
|
required: true
|
|
type: choice
|
|
options:
|
|
- staging
|
|
- prod
|
|
action:
|
|
description: 'Terraform action'
|
|
required: true
|
|
type: choice
|
|
options:
|
|
- plan
|
|
- apply
|
|
- destroy
|
|
auto_approve:
|
|
description: 'Auto-approve apply/destroy (use with caution)'
|
|
required: false
|
|
type: boolean
|
|
default: false
|
|
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
id-token: write # Required for OIDC authentication
|
|
issues: write
|
|
|
|
env:
|
|
TF_VERSION: '1.7.0'
|
|
TF_WORKING_DIR: '.'
|
|
|
|
jobs:
|
|
terraform-deploy:
|
|
name: Terraform ${{ inputs.action }} - ${{ inputs.environment }}
|
|
runs-on: ubuntu-latest
|
|
environment: ${{ inputs.environment }}
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
|
|
- name: Setup Terraform
|
|
uses: hashicorp/setup-terraform@v3
|
|
with:
|
|
terraform_version: ${{ env.TF_VERSION }}
|
|
|
|
# Configure cloud provider credentials
|
|
# Example for AWS:
|
|
- name: Configure AWS Credentials
|
|
if: ${{ vars.CLOUD_PROVIDER == 'aws' }}
|
|
uses: aws-actions/configure-aws-credentials@v4
|
|
with:
|
|
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
|
|
aws-region: ${{ vars.AWS_REGION || 'us-east-1' }}
|
|
|
|
# Example for Azure:
|
|
# - name: Azure Login
|
|
# if: ${{ vars.CLOUD_PROVIDER == 'azure' }}
|
|
# uses: azure/login@v1
|
|
# with:
|
|
# creds: ${{ secrets.AZURE_CREDENTIALS }}
|
|
|
|
# Example for GCP:
|
|
# - name: Authenticate to Google Cloud
|
|
# if: ${{ vars.CLOUD_PROVIDER == 'gcp' }}
|
|
# uses: google-github-actions/auth@v2
|
|
# with:
|
|
# workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
|
|
# service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
|
|
|
|
- name: Terraform Init
|
|
run: |
|
|
terraform init \
|
|
-backend-config="key=${{ inputs.environment }}/terraform.tfstate" \
|
|
-backend-config="bucket=${{ vars.TF_STATE_BUCKET }}" \
|
|
-backend-config="region=${{ vars.AWS_REGION || 'us-east-1' }}"
|
|
working-directory: ${{ env.TF_WORKING_DIR }}
|
|
|
|
- name: Terraform Workspace
|
|
run: |
|
|
terraform workspace select ${{ inputs.environment }} || terraform workspace new ${{ inputs.environment }}
|
|
working-directory: ${{ env.TF_WORKING_DIR }}
|
|
|
|
- name: Terraform Plan
|
|
id: plan
|
|
run: |
|
|
terraform plan \
|
|
-var-file="environments/${{ inputs.environment }}.tfvars" \
|
|
-out=tfplan \
|
|
-no-color
|
|
working-directory: ${{ env.TF_WORKING_DIR }}
|
|
|
|
- name: Upload Plan
|
|
uses: actions/upload-artifact@v6.0.0
|
|
with:
|
|
name: tfplan-${{ inputs.environment }}-${{ github.run_number }}
|
|
path: ${{ env.TF_WORKING_DIR }}/tfplan
|
|
retention-days: 30
|
|
|
|
- name: Terraform Apply
|
|
if: inputs.action == 'apply' && (inputs.auto_approve || inputs.environment != 'prod')
|
|
id: apply
|
|
run: |
|
|
terraform apply -auto-approve tfplan
|
|
working-directory: ${{ env.TF_WORKING_DIR }}
|
|
|
|
- name: Terraform Apply (Production - Manual Approval Required)
|
|
if: inputs.action == 'apply' && inputs.environment == 'prod' && !inputs.auto_approve
|
|
id: apply_prod
|
|
run: |
|
|
echo "Production deployment requires manual approval"
|
|
echo "Please review the plan and approve in GitHub environment settings"
|
|
terraform apply tfplan
|
|
working-directory: ${{ env.TF_WORKING_DIR }}
|
|
|
|
- name: Terraform Destroy
|
|
if: inputs.action == 'destroy' && inputs.auto_approve
|
|
id: destroy
|
|
run: |
|
|
terraform destroy \
|
|
-var-file="environments/${{ inputs.environment }}.tfvars" \
|
|
-auto-approve
|
|
working-directory: ${{ env.TF_WORKING_DIR }}
|
|
|
|
- name: Terraform Output
|
|
if: inputs.action == 'apply' && (steps.apply.outcome == 'success' || steps.apply_prod.outcome == 'success')
|
|
id: output
|
|
run: terraform output -json
|
|
working-directory: ${{ env.TF_WORKING_DIR }}
|
|
|
|
- name: Comment on Issue/PR
|
|
if: always()
|
|
uses: actions/github-script@v6 # TODO: Replace with curl for Gitea compatibility
|
|
with:
|
|
script: |
|
|
const fs = require('fs');
|
|
const action = '${{ inputs.action }}';
|
|
const env = '${{ inputs.environment }}';
|
|
const outcome = '${{ steps.apply.outcome || steps.destroy.outcome || steps.plan.outcome }}';
|
|
|
|
let body = `## Terraform ${action.toUpperCase()} - ${env}\n\n`;
|
|
body += `**Status:** ${outcome === 'success' ? '✅ Success' : '❌ Failed'}\n`;
|
|
body += `**Environment:** \`${env}\`\n`;
|
|
body += `**Action:** \`${action}\`\n`;
|
|
body += `**Triggered by:** @${{ github.actor }}\n\n`;
|
|
|
|
if (action === 'apply' && outcome === 'success') {
|
|
body += '### Infrastructure Updated Successfully\n\n';
|
|
try {
|
|
const outputs = '${{ steps.output.outputs.stdout }}';
|
|
body += '<details><summary>Terraform Outputs</summary>\n\n';
|
|
body += '```json\n' + outputs + '\n```\n\n';
|
|
body += '</details>\n';
|
|
} catch (e) {
|
|
body += '_Outputs not available_\n';
|
|
}
|
|
}
|
|
|
|
// Post to issue if triggered from issue
|
|
if (context.issue.number) {
|
|
github.rest.issues.createComment({
|
|
issue_number: context.issue.number,
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
body: body
|
|
});
|
|
}
|
|
|
|
- name: Summary
|
|
if: always()
|
|
run: |
|
|
echo "### Terraform Deployment Summary" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "- **Environment:** ${{ inputs.environment }}" >> $GITHUB_STEP_SUMMARY
|
|
echo "- **Action:** ${{ inputs.action }}" >> $GITHUB_STEP_SUMMARY
|
|
echo "- **Status:** ${{ job.status }}" >> $GITHUB_STEP_SUMMARY
|
|
echo "- **Run Number:** ${{ github.run_number }}" >> $GITHUB_STEP_SUMMARY
|