Skip to content

Commit df37d00

Browse files
committed
feat: plone-theme-upload-notify
BIBLI-60
1 parent 196c4c3 commit df37d00

File tree

4 files changed

+172
-0
lines changed

4 files changed

+172
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## [v3.8] - 2024-08-08
4+
### Added
5+
- plone-theme-build-push-notify
6+
37
## [v3.7.2] - 2024-07-31
48
### Fixed
59
- rundeck-notify

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,25 @@ Test a Plone package and optionally notify via a mattermost webhook
133133

134134
/
135135

136+
---
137+
### plone-theme-build-push-notify
138+
139+
Build a theme, upload it to a plone site and optionally notify on Mattermost
140+
141+
#### Inputs
142+
143+
| name | required | type | default | description |
144+
| ---------------------- | -------- | ------ | -------------| ----------- |
145+
| THEME_PATH | yes | string | | Folder where theme files are located |
146+
| PLONE_URL | yes | string | | URL of the Plone site |
147+
| PLONE_USERNAME | yes | string | | Username to login to Plone |
148+
| PLONE_PASSWORD | yes | string | | Password to login to Plone |
149+
| MATTERMOST_WEBHOOK_URL | no | string | | Webhook URL to send notifications on Mattermost |
150+
151+
#### Example of usage
152+
153+
/
154+
136155
---
137156
### rundeck-notify
138157

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Upload plone theme and notify on Mattermost
2+
description: Upload a theme to a plone site and optionally notify on Mattermost
3+
inputs:
4+
THEME_PATH:
5+
description: 'Folder where theme files are located'
6+
required: true
7+
PLONE_URL:
8+
description: 'URL of the Plone site'
9+
required: true
10+
PLONE_USERNAME:
11+
description: 'Username to login to Plone'
12+
required: true
13+
PLONE_PASSWORD:
14+
description: 'Password to login to Plone'
15+
required: true
16+
MATTERMOST_WEBHOOK_URL:
17+
description: 'Webhook URL to send notifications on Mattermost, if not provided, notifications will not be sent'
18+
required: false
19+
runs:
20+
using: 'composite'
21+
steps:
22+
- name: Install curl
23+
run: |
24+
if which curl > /dev/null ; then
25+
echo "curl is already installed"
26+
else
27+
sudo apt-get update && sudo apt-get install -y curl
28+
fi
29+
shell: bash
30+
- name: Install pip3 and python packages
31+
run: |
32+
if which pip3 > /dev/null ; then
33+
echo "pip3 is already installed"
34+
else
35+
sudo apt-get update && sudo apt-get install -y python3-pip && pip3 install bs4 requests
36+
fi
37+
shell: bash
38+
- name: Install node dev dependencies
39+
run: |
40+
pnpm install --no-frozen-lockfile
41+
shell: bash
42+
- name: Build themes
43+
run: |
44+
echo Building theme for ${{ inputs.THEME_PATH }}
45+
pnpm --theme=${{ inputs.THEME_PATH }} build
46+
shell: bash
47+
- name: Upload theme
48+
run: |
49+
python3 ${{ github.action_path }}/theme_uploader.py ${{ inputs.PLONE_URL }} ${{ inputs.PLONE_USERNAME }} ${{ inputs.PLONE_PASSWORD }} ${{ inputs.THEME_PATH }} theme.zip
50+
shell: bash
51+
- name : Send notification on Mattermost
52+
if: ${{ inputs.MATTERMOST_WEBHOOK_URL != '' }}
53+
uses: IMIO/gha/[email protected]
54+
with:
55+
MATTERMOST_WEBHOOK_URL: ${{ inputs.MATTERMOST_WEBHOOK_URL }}
56+
MESSAGE: "Theme has been successfully uploaded to Plone site ${{ inputs.PLONE_URL }}"
57+
- name : Send failure notification on Mattermost
58+
if: ${{ failure() && inputs.MATTERMOST_WEBHOOK_URL != '' }}
59+
uses: IMIO/gha/[email protected]
60+
with:
61+
MATTERMOST_WEBHOOK_URL: ${{ inputs.MATTERMOST_WEBHOOK_URL }}
62+
MESSAGE: "An error has been encountered while uploading theme to Plone site ${{ inputs.PLONE_URL }}"
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
"""Plone theme uploader
4+
5+
This script is used to upload a theme to a Plone instance.
6+
7+
Usage:
8+
python theme_uploader.py INSTANCE_URL USERNAME PASSWORD THEME_LOCATION
9+
"""
10+
11+
from bs4 import BeautifulSoup
12+
13+
import requests
14+
import requests.cookies
15+
import sys
16+
17+
INSTANCE_URL = sys.argv[1]
18+
USERNAME = sys.argv[2]
19+
PASSWORD = sys.argv[3]
20+
THEME_PATH = sys.argv[4]
21+
THEME_FILENAME = sys.argv[5]
22+
23+
24+
def authenticate(
25+
session: requests.Session, login_url: str, username: str, password: str
26+
) -> requests.Response:
27+
url = INSTANCE_URL + "/failsafe_login"
28+
data = {
29+
"__ac_name": USERNAME,
30+
"__ac_password": PASSWORD,
31+
"came_from": f"{INSTANCE_URL}/@@theming-controlpanel",
32+
"buttons.login": "Se connecter",
33+
}
34+
response = session.post(url, data=data)
35+
return response
36+
37+
38+
def get_cookie(response: requests.Response) -> requests.cookies.RequestsCookieJar:
39+
return response.cookies
40+
41+
42+
def get_token(response: requests.Response) -> str:
43+
soup = BeautifulSoup(response.text, "html.parser")
44+
authenticator = soup.find(attrs={"name": "_authenticator"})
45+
return authenticator["value"]
46+
47+
48+
def upload_theme(
49+
session: requests.Session,
50+
instance_url: str,
51+
token: str,
52+
theme_path: str,
53+
theme_filename: str,
54+
) -> requests.Response:
55+
url = instance_url + "/@@theming-controlpanel"
56+
with open(f"{theme_path}/{theme_filename}", "rb") as file_content:
57+
file = {"themeArchive": (theme_filename, file_content, "application/zip")}
58+
data = {
59+
"replaceExisting:boolean": "1",
60+
"form.button.Import": "1",
61+
"enableNewTheme:boolean": "1",
62+
"_authenticator": token,
63+
}
64+
response = session.post(url, files=file, data=data)
65+
return response
66+
67+
68+
def main():
69+
session = requests.Session()
70+
print("Authenticating to Plone instance...")
71+
response = authenticate(session, INSTANCE_URL, USERNAME, PASSWORD)
72+
if "__ac=deleted" in response.headers["set-cookie"]:
73+
print("Authentication failed")
74+
sys.exit(1)
75+
print("Getting token...")
76+
token = get_token(response)
77+
print("Uploading theme...")
78+
response = upload_theme(session, INSTANCE_URL, token, THEME_PATH, THEME_FILENAME)
79+
if response.status_code == 200:
80+
print("Theme uploaded successfully")
81+
else:
82+
print("Theme upload failed... Error code: ", response.status_code)
83+
sys.exit(1)
84+
85+
86+
if __name__ == "__main__":
87+
main()

0 commit comments

Comments
 (0)