Skip to content

Commit

Permalink
chore: transform script into a composite action
Browse files Browse the repository at this point in the history
  • Loading branch information
juliamrch committed Jul 18, 2024
1 parent 73fed71 commit acd8693
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 184 deletions.
45 changes: 45 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
on:
pull_request_target:
types: [opened, closed, synchronize, reopened]
branches: [ main ]

jobs:
deploy:
name: Deploy/redeploy review app
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v4
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.ref }}
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: Create review app
uses: juliamrch/gh-action-composite@v20
env:
CLEVER_SECRET: ${{ secrets.CLEVER_SECRET }}
CLEVER_TOKEN: ${{ secrets.CLEVER_TOKEN }}
ORGA_ID: ${{ secrets.ORGA_ID }}
GH_CC_RUN_SUCCEEDED_HOOK: ${{ secrets.CC_RUN_SUCCEEDED_HOOK }}
with:
type: 'static-apache'
set-env: true
environment: 'review'
- name: Comment PR
uses: actions/github-script@v7
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
script: |
const issue_number = context.payload.pull_request.number;
const message = `Deployment has finished 👁️👄👁️ Your app is available [here](https://${{ github.event.pull_request.base.repo.name }}-PR-${{ github.event.number }}.cleverapps.io)`;
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue_number,
body: message
});
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_Store
104 changes: 63 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,46 @@ The action will consider both branches on the same repository, and pull requests
- An [organisation](https://developers.clever-cloud.com/doc/account/administrate-organization/) in Clever Cloud
- [Clever Cloud CLI](https://developers.clever-cloud.com/doc/cli/getting_started/) installed in your machine to inject your tokens

### Mandatory configuration

Add the following secrets to your repository, in **Settings > Secrets and variables**:

- `CLEVER_SECRET` and `CLEVER_TOKEN`: find them in your `clever-tools.json` after installing the CLI (example path on Mac: `~/.config/clever-cloud/clever-tools.json`)
- `ORGA_ID`: the organisation in which your app is created

For better security, we advise generating a specific `CLEVER_SECRET` and `CLEVER_TOKEN` for GitHub Actions. Follow these steps to do so:

1. Create a new user with a new email adress on Clever Cloud
2. Create a specific organization for deploying review apps
3. From your terminal, run `clever logout` and `clever login` right after
4. Log into the Console with your new user credetials
5. Get the generated `CLEVER_SECRET` and `CLEVER_TOKEN` and inject it into your repository secrets

Run `clever login` again and connect from your main account to set your personal tokens. Your GitHub Acction user's tokens won't be revoked and will be used only from GitHub.

## How to Use this Action

Place this script in your repository in `.github/workflows/` and modify the following values:
1. In your `.github/workflow/review-app.yml`, define the event trigger for running the action:

- `<type>` for the type of app
- `region` for where you want the app to be deployed
- `<VARIABLE_NAME>` and `variable_value` for your environment variables
```yaml
on:
pull_request_target:
types: [opened, closed, synchronize, reopened]
branches: [ main ]
```
2. Then, define the mandatory input:
```yaml
- name: Create review app
uses: CleverCloud/clever-cloud-review-app@latest
env:
CLEVER_SECRET: ${{ secrets.CLEVER_SECRET }}
CLEVER_TOKEN: ${{ secrets.CLEVER_TOKEN }}
ORGA_ID: ${{ secrets.ORGA_ID }}
with:
type: '<type-of-app>'
```
### Values for `--type`

Expand All @@ -43,6 +76,32 @@ Place this script in your repository in `.github/workflows/` and modify the foll
- `static-apache`: for static (HTML only) websites
- `war`: for applications deployed as war files

### Inject secrets and variables

To inject your app secrets and environment variables on Clever Cloud, add them to your GitHub repository in **Settings > Secrets and variables**, then add them with an `GH_` prefix in your workflow file. Finally, enable the injection with `set-env: true`:

```yaml
name: Create review app
uses: CleverCloud/clever-cloud-review-app@latest
env:
CLEVER_SECRET: ${{ secrets.CLEVER_SECRET }}
CLEVER_TOKEN: ${{ secrets.CLEVER_TOKEN }}
ORGA_ID: ${{ secrets.ORGA_ID }}
GH_CC_RUN_SUCCEEDED_HOOK: ${{ secrets. CC_RUN_SUCCEEDED_HOOK }} # This envrironment variable will be set on Clever Cloud
with:
type: '<type-of-app>'
set-env: true # Enables the command to set en vars on Clever Cloud
```

## Options

You can override default options by defining `region`, `domain`, `name`, and `alias`. Default values are:

- `region`=`par` (Paris)
- `domain`=`<repo-name>-PR-#.cleverapps.io`
- `name`=`<repo-name>-PR-#>`
- `alias`=`<repo-name>-PR-#>`

### Values for `--region`

- `par` (Paris, [Clever Cloud](https://www.clever-cloud.com/infrastructure/))
Expand All @@ -54,40 +113,3 @@ Place this script in your repository in `.github/workflows/` and modify the foll
- `sgp` (Singapore, OVHcloud)
- `syd` (Sydney, OVHcloud)
- `wsw` (Warsaw, OVHcloud)

## Secrets You'll Need

- `CLEVER_SECRET` and `CLEVER_TOKEN`: find them in your `clever-tools.json` after installing the CLI (example path on Mac: `~/.config/clever-cloud/clever-tools.json`)
- `ORGA_ID`: the organisation in which your app is created

For better security, we advise generating a specific `CLEVER_SECRET` and `CLEVER_TOKEN` for GitHub Actions. Follow these steps to do so:

1. Create a new user with a new email adress on Clever Cloud
2. Create a specific organization for deploying review apps
3. From your terminal, run `clever logout` and `clever login` right after
4. Log into the Console with your new user credetials
5. Get the generated `CLEVER_SECRET` and `CLEVER_TOKEN` and inject it into your repository secrets

Run `clever login` again and connect from your main account to set your personal tokens. Your GitHub Acction user's tokens won't be revoked and will be used only from GitHub.

## Inject App Secrets

You can pass more secrets in your app by setting them in your GitHub repository and listing them in `env` and adding them like this : `<A_SECRET>: ${{ secrets.<A_SECRET> }}`.

Then when injecting environment variables in `Create and deploy app` step, add `clever env set <A_SECRET> "$<A_SECRET>"`.

For better security, follow this syntax and store the secrets in-memory for each step, to avoid exploits and leaks, instead ouf sourcing them directly in a shell script.

### Example Script

```yaml
step: Create and deploy app
env:
...
HUGO_VERSION: ${{ secrets.HUGO_VERSION }}

...
- name: Set evironment variables
run: |
clever env set HUGO_VERSION "$HUGO_VERSION"
```
210 changes: 67 additions & 143 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,145 +1,69 @@
name: Clever Cloud Review App on Pull Requests
name: 'Clever Cloud review app on PRs'
description: 'Deploy a review app on Clever Cloud when a PR is opened'

description: Deploy, sync and delete review apps on Clever Cloud for every pull request targeting the `main` branch
branding:
icon: upload-cloud
colore: red

on:
pull_request_target:
types: [opened, closed, synchronize, reopened]
branches: [ main ]
inputs:
type:
description: 'Which type of app to create'
required: true
name:
description: 'The name of your app'
required: true
default: ${{ github.event.pull_request.base.repo.name }}-PR-${{ github.event.number }}
alias:
description: 'The alias of your app'
required: true
default: ${{ github.event.pull_request.base.repo.name }}-PR-${{ github.event.number }}
region:
description: 'The region to deploy on'
required: true
default: 'par'
organization:
description: 'The organization to deploy on'
required: true
default: $ORGA_ID
domain:
description: 'The domain to use for the app'
required: false
default: ${{ github.event.pull_request.base.repo.name }}-PR-${{ github.event.number }}.cleverapps.io
set-env:
description: 'Set environment variables'
type: boolean
required: false
default: false
environment:
description: 'Environment to run tests against'
type: environment
required: true
default: ''
runs:
using: "composite"
steps:
- name: Install clever-tools
shell: bash
run: npm install -g clever-tools
- name: Execute commands based on action
run: |
if [ "${{ github.event.action }}" = 'opened' ] || [ "${{ github.event.action }}" = 'reopened' ]; then
clever create --type ${{ inputs.type }} ${{ inputs.name }} --alias ${{ inputs.alias }} --region ${{ inputs.region }} --org ${{ inputs.organization }}
clever domain add ${{ inputs.domain }}
# Only select environment variables with GH_ prefix
# to exclude GitHub runner variables
if ${{ inputs.set-env }}; then
# Remove prefix from print
for var in $(env | awk -F= '/^GH_/ { print $1 }')
do
real_var=${var#GH_}
# Inject variable in the app on Clever Cloud
clever env set $real_var "${!var}"
done
# Inject these secrets in your GitHub repository.
# List more secrets if needed, for example: HUGO_VERSION: ${{ secrets.HUGO_VERSION }}


jobs:
deploy:
if: github.event.action == 'opened'|| github.event.action == 'reopened'
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
contents: read
environment:
name: PR review apps
steps:
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v4
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.ref }}
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls ${{ github.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."
- name: install clever-tools
run: npm install -g clever-tools
- name: Create and deploy app
env:
CLEVER_SECRET: ${{ secrets.CLEVER_SECRET }}
CLEVER_TOKEN: ${{ secrets.CLEVER_TOKEN }}
ORGA_ID: ${{ secrets.ORGA_ID }}
# Use "clever create" to deploy your app.
# Replace <type> and <region>
run: |
clever create --type <type> ${{ github.event.pull_request.base.repo.name }}-PR-${{ github.event.number }} --alias ${{ github.event.pull_request.base.repo.name }}-PR-${{ github.event.number }} --region <region> --org "$ORGA_ID"
# Set environment variable with "clever env set".
# For example: clever env set CC_WEBROOT "/public"
# Inject your secrets as well, for ex:
#clever env set HUGO_VERSION ${{env.HUGO_VERSION}}
clever env set <VARIABLE_NAME> "<variable_value>"
# Set review app domain with "clever domain add".
clever domain add ${{ github.event.pull_request.base.repo.name }}-PR-${{ github.event.number }}.cleverapps.io
clever deploy
# Post your domain in PR's discussion
- name: Comment PR
uses: actions/github-script@v5
with:
script: |
const issue_number = context.payload.pull_request.number;
const message = `Deployment has finished 👁️👄👁️ Your app is available [here](https://${{ github.event.pull_request.base.repo.name }}-PR-${{ github.event.number }}.cleverapps.io)`;
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue_number,
body: message
});
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# Deploy review apps on new commits
update:
if: github.event.action == 'synchronize'
runs-on: ubuntu-latest
permissions:
issues: write
contents: read
pull-requests: write
steps:
- name: Check out repository code
uses: actions/checkout@v4
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.ref }}
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: install clever-tools
run: npm install -g clever-tools
- name: Link and update app
env:
CLEVER_SECRET: ${{ secrets.CLEVER_SECRET }}
CLEVER_TOKEN: ${{ secrets.CLEVER_TOKEN }}
ORGA_ID: ${{ secrets.ORGA_ID }}
run: |
clever link -o "$ORGA_ID" ${{ github.event.pull_request.base.repo.name }}-PR-${{ github.event.number }}
clever deploy
- name: Comment PR
uses: actions/github-script@v5
with:
script: |
const issue_number = context.payload.pull_request.number;
const message = `🚀 Your app has been updated and is available [here](https://${{ github.event.pull_request.base.repo.name }}-PR-${{ github.event.number }}.cleverapps.io)`;
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue_number,
body: message
});
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# Delete review app when the PR is closed (merged or not)
delete:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
if: always() && github.event_name == 'pull_request_target' && github.event.action == 'closed'
steps:
- name: install clever-tools
run: npm install -g clever-tools
- name: Delete app
run: |
clever link -o "$ORGA_ID" ${{ github.event.pull_request.base.repo.name }}-PR-${{ github.event.number }}
clever delete --alias ${{ github.event.pull_request.base.repo.name }}-PR-${{ github.event.number }} --yes
- name: Comment PR
uses: actions/github-script@v5
with:
script: |
const issue_number = context.payload.pull_request.number;
const message = `Your review app has been deleted 👋`;
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue_number,
body: message
});
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
clever deploy
fi
elif [ "${{ github.event.action }}" = 'synchronize' ]; then
clever link -o "$ORGA_ID" ${{ inputs.name }}
clever deploy --force
elif [ "${{ github.event.action }}" = 'closed' ]; then
clever link -o "$ORGA_ID" ${{ inputs.name }}
clever delete --alias ${{ inputs.alias }}
fi
shell: bash
Loading

0 comments on commit acd8693

Please sign in to comment.