Add Gitea webhook
parent
7e0f34b9af
commit
39a5f5e006
|
@ -12,13 +12,16 @@ steps:
|
||||||
- pip3 install requests python-dotenv --quiet
|
- pip3 install requests python-dotenv --quiet
|
||||||
- python3 deploy/portainer/deploy.py
|
- python3 deploy/portainer/deploy.py
|
||||||
--PORTAINER https://dvportainer.privatedns.org
|
--PORTAINER https://dvportainer.privatedns.org
|
||||||
--API_KEY=ptr_RwxH2Cd+htdD2FoFiG46erT9beyvj9VoF3BrQPtDH3Q=
|
--PORTAINER_API_KEY=ptr_RwxH2Cd+htdD2FoFiG46erT9beyvj9VoF3BrQPtDH3Q=
|
||||||
--PORTAINER_EP=CICD-runner
|
--PORTAINER_EP=CICD-runner
|
||||||
|
--GITEA_API_KEY=f449c74ec7f04e54fe1e481eae43492b34cea406
|
||||||
--DEPLOY_REPO_URL=${DRONE_REPO_LINK}
|
--DEPLOY_REPO_URL=${DRONE_REPO_LINK}
|
||||||
--DEPLOY_REF=${DRONE_COMMIT_REF}
|
--DEPLOY_REF=${DRONE_COMMIT_REF}
|
||||||
--DEPLOY_HOST=dvdemo.privatedns.org
|
--DEPLOY_HOST=dvdemo.privatedns.org
|
||||||
--DEPLOY_NAME=${DRONE_COMMIT_SHA}
|
--DEPLOY_NAME=${DRONE_COMMIT_SHA}
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
branch:
|
event:
|
||||||
- main
|
- pull_request
|
||||||
|
action:
|
||||||
|
- opened
|
|
@ -1,6 +1,7 @@
|
||||||
PORTAINER=https://dvportainer.privatedns.org
|
PORTAINER=https://dvportainer.privatedns.org
|
||||||
API_KEY=ptr_RwxH2Cd+htdD2FoFiG46erT9beyvj9VoF3BrQPtDH3Q=
|
PORTAINER_API_KEY=ptr_RwxH2Cd+htdD2FoFiG46erT9beyvj9VoF3BrQPtDH3Q=
|
||||||
PORTAINER_EP=CICD-runner
|
PORTAINER_EP=CICD-runner
|
||||||
|
GITEA_API_KEY=f449c74ec7f04e54fe1e481eae43492b34cea406
|
||||||
DEPLOY_REPO_URL=https://dvgit.privatedns.org/lars/DeployTests
|
DEPLOY_REPO_URL=https://dvgit.privatedns.org/lars/DeployTests
|
||||||
DEPLOY_REF=refs/heads/main
|
DEPLOY_REF=refs/heads/main
|
||||||
DEPLOY_HOST=dvdemo.privatedns.org
|
DEPLOY_HOST=dvdemo.privatedns.org
|
||||||
|
|
|
@ -5,16 +5,19 @@ import sys
|
||||||
import argparse
|
import argparse
|
||||||
import requests
|
import requests
|
||||||
import json
|
import json
|
||||||
|
import uuid
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from string import Template
|
from string import Template
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
required_env_vars = {
|
required_env_vars = {
|
||||||
'PORTAINER': 'The portainer instance to deploy to',
|
'PORTAINER': 'The portainer instance to deploy to',
|
||||||
'API_KEY': 'API-Key to access portainer instance',
|
'PORTAINER_API_KEY': 'API-Key to access portainer instance',
|
||||||
'PORTAINER_EP': 'Portainer Environment EndPoint to deploy to',
|
'PORTAINER_EP': 'Portainer Environment EndPoint to deploy to',
|
||||||
|
'GITEA_API_KEY': 'API-Key to access Gitea instance',
|
||||||
'DEPLOY_REPO_URL': 'The repository URL to deploy',
|
'DEPLOY_REPO_URL': 'The repository URL to deploy',
|
||||||
'DEPLOY_REF': 'The git ref to deploy',
|
'DEPLOY_REF': 'The git ref to deploy',
|
||||||
'DEPLOY_HOST': 'The host name under which the deployment will be reachable',
|
'DEPLOY_HOST': 'The host name under which the deployment will be reachable',
|
||||||
|
@ -41,24 +44,29 @@ if not_parsed:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
portainer=args.PORTAINER
|
|
||||||
api_key=args.API_KEY
|
|
||||||
portainer_ep=args.PORTAINER_EP
|
|
||||||
|
|
||||||
# Deploy variables to substitute in portainer deploy template
|
# Deploy variables to substitute in portainer deploy template
|
||||||
deploy_variables = {key: getattr(args, key) for key in
|
deploy_variables = {key: getattr(args, key) for key in
|
||||||
['DEPLOY_REPO_URL', 'DEPLOY_HOST', 'DEPLOY_NAME', 'DEPLOY_REF']
|
['DEPLOY_REPO_URL', 'DEPLOY_HOST', 'DEPLOY_NAME', 'DEPLOY_REF']
|
||||||
}
|
}
|
||||||
|
deploy_variables['DEPLOY_WEBHOOK'] = str(uuid.uuid4())
|
||||||
|
|
||||||
|
portainer=args.PORTAINER
|
||||||
|
portainer_api_key=args.PORTAINER_API_KEY
|
||||||
|
portainer_ep=args.PORTAINER_EP
|
||||||
|
gitea_api_key=args.GITEA_API_KEY
|
||||||
|
deploy_repo=deploy_variables['DEPLOY_REPO_URL']
|
||||||
|
deploy_webhook=deploy_variables['DEPLOY_WEBHOOK']
|
||||||
|
deploy_ref=deploy_variables['DEPLOY_REF']
|
||||||
|
|
||||||
### Find CICD-runner portainer environment endpointId ###
|
### Find CICD-runner portainer environment endpointId ###
|
||||||
headers = {
|
portainer_headers = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'X-API-Key': api_key,
|
'X-API-Key': portainer_api_key,
|
||||||
}
|
}
|
||||||
url = f'{portainer}/api/endpoints'
|
endpoint_url = f'{portainer}/api/endpoints'
|
||||||
json_endpoints = None
|
json_endpoints = None
|
||||||
try:
|
try:
|
||||||
response = requests.get(url, headers=headers)
|
response = requests.get(endpoint_url, headers=portainer_headers)
|
||||||
response.raise_for_status() # Raise HTTPError for bad requests
|
response.raise_for_status() # Raise HTTPError for bad requests
|
||||||
json_endpoints = response.json()
|
json_endpoints = response.json()
|
||||||
|
|
||||||
|
@ -77,26 +85,75 @@ else:
|
||||||
|
|
||||||
|
|
||||||
### Template substitution for the portainer stack deployment ###
|
### Template substitution for the portainer stack deployment ###
|
||||||
portainer_deploy_json = None
|
portainer_deploy_payload = {
|
||||||
template_file = f'{Path( __file__ ).parent.absolute()}/portainer_deploy.template.json'
|
"additionalFiles": [
|
||||||
with open(template_file, 'r') as file:
|
"deploy/portainer/portainer_deploy.docker-compose.yml"
|
||||||
portainer_template = Template(file.read())
|
],
|
||||||
|
"autoUpdate": {
|
||||||
# Perform variable substitution
|
"webhook": f"{deploy_variables['DEPLOY_WEBHOOK']}"
|
||||||
portainer_deploy_json = portainer_template.substitute(**deploy_variables)
|
},
|
||||||
|
"composeFile": "docker-compose.yml",
|
||||||
|
"env": [
|
||||||
|
{
|
||||||
|
"name": "HOST",
|
||||||
|
"value": f"{deploy_variables['DEPLOY_HOST']}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "COMPOSE_PROJECT_NAME",
|
||||||
|
"value": f"{deploy_variables['DEPLOY_NAME']}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fromAppTemplate": False,
|
||||||
|
"name": f"{deploy_variables['DEPLOY_NAME']}",
|
||||||
|
"repositoryAuthentication": True,
|
||||||
|
"repositoryUsername": "cicd",
|
||||||
|
"repositoryPassword": "gJ6@$7ZjWGyV4%i",
|
||||||
|
"repositoryReferenceName": f"{deploy_variables['DEPLOY_REF']}",
|
||||||
|
"repositoryURL": f"{deploy_variables['DEPLOY_REPO_URL']}",
|
||||||
|
"tlsskipVerify": False
|
||||||
|
}
|
||||||
|
|
||||||
### Deploy to portainer ###
|
### Deploy to portainer ###
|
||||||
headers = {
|
deploy_url = f'{portainer}/api/stacks/create/standalone/repository?endpointId={endpoint_id}'
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'X-API-Key': api_key,
|
|
||||||
}
|
|
||||||
url = f'{portainer}/api/stacks/create/standalone/repository?endpointId={endpoint_id}'
|
|
||||||
try:
|
try:
|
||||||
response = requests.post(url, headers=headers, json=json.loads(portainer_deploy_json))
|
response = requests.post(deploy_url, headers=portainer_headers, json=portainer_deploy_payload)
|
||||||
response.raise_for_status() # Raise HTTPError for bad requests
|
response.raise_for_status() # Raise HTTPError for bad requests
|
||||||
response_data = response.json() # Parse response JSON
|
deploy_response = response.json()
|
||||||
|
|
||||||
except requests.exceptions.RequestException as err:
|
except requests.exceptions.RequestException as err:
|
||||||
raise Exception(f'Could not deploy portainer stack: {err}')
|
raise Exception(f'Could not deploy portainer stack: {err}')
|
||||||
|
|
||||||
|
### Add Webhook to Gitea ###
|
||||||
|
repo_url = urlparse(deploy_repo)
|
||||||
|
gitea = f"{repo_url.scheme}://{repo_url.netloc}"
|
||||||
|
repo_path = repo_url.path
|
||||||
|
repo_parts = repo_path.strip('/').split('/')
|
||||||
|
owner = repo_parts[0]
|
||||||
|
repo = repo_parts[1]
|
||||||
|
|
||||||
|
ref_parts = deploy_ref.strip('/').split('/')
|
||||||
|
branch = ref_parts[2]
|
||||||
|
|
||||||
|
webhook_payload = {
|
||||||
|
"type": "gitea",
|
||||||
|
"branch_filter": f"{branch}",
|
||||||
|
"config": {
|
||||||
|
"url": f"{portainer}/api/stacks/webhooks/{deploy_webhook}",
|
||||||
|
"content_type": "json"
|
||||||
|
},
|
||||||
|
"events": ["push"], # You can specify other events as needed
|
||||||
|
"active": True
|
||||||
|
}
|
||||||
|
|
||||||
|
webhook_url = f'{gitea}/api/v1/repos/{owner}/{repo}/hooks'
|
||||||
|
webhook_headers = {
|
||||||
|
"Authorization": f"token {gitea_api_key}"
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
response = requests.post(webhook_url, headers=webhook_headers, json=webhook_payload)
|
||||||
|
response.raise_for_status() # Raise HTTPError for bad requests
|
||||||
|
webhook_response = response.json()
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as err:
|
||||||
|
raise Exception(f'Could not add webhook to Gitea: {err}')
|
||||||
print(f'Successfully deployed project')
|
print(f'Successfully deployed project')
|
|
@ -1,31 +0,0 @@
|
||||||
{
|
|
||||||
"additionalFiles": [
|
|
||||||
"deploy/portainer/portainer_deploy.docker-compose.yml"
|
|
||||||
],
|
|
||||||
"autoUpdate": {
|
|
||||||
"forcePullImage": false,
|
|
||||||
"forceUpdate": false,
|
|
||||||
"interval": "1m30s",
|
|
||||||
"jobID": "15",
|
|
||||||
"webhook": "05de31a2-79fa-4644-9c12-faa67e5c49f0"
|
|
||||||
},
|
|
||||||
"composeFile": "docker-compose.yml",
|
|
||||||
"env": [
|
|
||||||
{
|
|
||||||
"name": "HOST",
|
|
||||||
"value": "${DEPLOY_HOST}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "COMPOSE_PROJECT_NAME",
|
|
||||||
"value": "${DEPLOY_NAME}"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"fromAppTemplate": false,
|
|
||||||
"name": "${DEPLOY_NAME}",
|
|
||||||
"repositoryAuthentication": true,
|
|
||||||
"repositoryUsername": "cicd",
|
|
||||||
"repositoryPassword": "gJ6@$$7ZjWGyV4%i",
|
|
||||||
"repositoryReferenceName": "${DEPLOY_REF}",
|
|
||||||
"repositoryURL": "${DEPLOY_REPO_URL}",
|
|
||||||
"tlsskipVerify": false
|
|
||||||
}
|
|
Loading…
Reference in New Issue