Skip to content

Commit 81af3ce

Browse files
committed
Enhance GitHub Actions workflow for driver deployment
- Added support for manual workflow dispatch with branch type selection for deploying to main or test environments. - Refactored deployment steps for improved clarity and organization, ensuring consistent execution of driver packaging and assignment. - Updated channel ID determination logic to handle both push events and manual dispatch scenarios effectively. - Improved logging and error handling throughout the deployment process for better visibility and debugging.
1 parent 089fc48 commit 81af3ce

File tree

1 file changed

+212
-177
lines changed

1 file changed

+212
-177
lines changed

.github/workflows/deploy.yml

Lines changed: 212 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -1,182 +1,217 @@
11
name: Deploy Drivers
22

33
on:
4-
push:
5-
branches:
6-
- main
7-
- test/**
4+
push:
5+
branches:
6+
- main
7+
- test/**
8+
workflow_dispatch:
9+
inputs:
10+
branch_type:
11+
description: "Deploy to which environment"
12+
required: true
13+
type: choice
14+
options:
15+
- main
16+
- test
17+
default: "main"
818

919
jobs:
10-
deploy:
11-
runs-on: ubuntu-latest
12-
13-
steps:
14-
- name: Checkout code
15-
uses: actions/checkout@v4
16-
17-
- name: Setup Node.js
18-
uses: actions/setup-node@v4
19-
with:
20-
node-version: "20"
21-
22-
- name: Install SmartThings CLI
23-
run: |
24-
npm install -g @smartthings/cli@latest
25-
26-
- name: Authenticate SmartThings CLI
27-
run: |
28-
smartthings auth --token "${{ secrets.SMARTTHINGS_PERSONAL_ACCESS_TOKEN }}"
29-
30-
- name: Setup dependencies
31-
run: |
32-
sudo apt-get update
33-
sudo apt-get install -y jq
34-
35-
- name: Find driver folders
36-
id: find-drivers
37-
run: |
38-
DRIVER_FOLDERS=()
39-
for dir in */; do
40-
if [[ -d "${dir}profiles" && -d "${dir}src" && -f "${dir}config.yml" ]]; then
41-
DRIVER_FOLDERS+=("$dir")
42-
fi
43-
done
44-
echo "folders=$(IFS=','; echo "${DRIVER_FOLDERS[*]}")" >> $GITHUB_OUTPUT
45-
echo "Found driver folders: ${DRIVER_FOLDERS[@]}"
46-
47-
- name: Update device profiles
48-
run: |
49-
IFS=',' read -ra FOLDERS <<< "${{ steps.find-drivers.outputs.folders }}"
50-
for folder in "${FOLDERS[@]}"; do
51-
echo "Processing profiles for: $folder"
52-
PROFILE_DIR="${folder}profiles"
53-
54-
if [[ ! -d "$PROFILE_DIR" ]]; then
55-
echo "Profile directory not found: $PROFILE_DIR"
56-
continue
57-
fi
58-
59-
shopt -s nullglob
60-
files=("$PROFILE_DIR"/*.yml)
61-
shopt -u nullglob
62-
63-
if [[ ${#files[@]} -eq 0 ]]; then
64-
echo "No YAML files found in $PROFILE_DIR"
65-
continue
66-
fi
67-
68-
for file in "${files[@]}"; do
69-
PROFILE_NAME=$(basename "$file" .yml)
70-
echo "Processing profile: $PROFILE_NAME"
71-
72-
PROFILE_ID=$(smartthings deviceprofiles --json 2>/dev/null | jq -r '.[] | select(.name=="'"$PROFILE_NAME"'") | .id' 2>/dev/null || echo "")
73-
74-
if [[ -n "$PROFILE_ID" && "$PROFILE_ID" != "null" ]]; then
75-
echo "Deleting existing profile: $PROFILE_NAME ($PROFILE_ID)"
76-
smartthings deviceprofiles:delete "$PROFILE_ID" >/dev/null 2>&1 || true
77-
fi
78-
79-
echo "Creating profile from file: $file"
80-
if ! smartthings deviceprofiles:create --input "$file" 2>&1; then
81-
echo "ERROR: Failed to create profile $PROFILE_NAME"
82-
continue
83-
fi
84-
85-
NEW_ID=$(smartthings deviceprofiles --json 2>/dev/null | jq -r '.[] | select(.name=="'"$PROFILE_NAME"'") | .id' 2>/dev/null || echo "")
86-
if [[ -z "$NEW_ID" || "$NEW_ID" == "null" ]]; then
87-
echo "ERROR: Failed to find created profile $PROFILE_NAME"
88-
continue
89-
fi
90-
91-
echo "Publishing profile: $PROFILE_NAME ($NEW_ID)"
92-
if ! smartthings deviceprofiles:publish "$NEW_ID" 2>&1; then
93-
echo "ERROR: Failed to publish profile $PROFILE_NAME"
94-
continue
95-
fi
96-
done
97-
done
98-
99-
- name: Determine channel ID
100-
id: channel
101-
run: |
102-
BRANCH_NAME="${{ github.ref_name }}"
103-
echo "Current branch: $BRANCH_NAME"
104-
105-
if [[ "$BRANCH_NAME" == "main" ]]; then
106-
CHANNEL_ID="${{ secrets.SMARTTHINGS_CHANNEL_ID_MAIN }}"
107-
if [[ -z "$CHANNEL_ID" ]]; then
108-
echo "ERROR: SMARTTHINGS_CHANNEL_ID_MAIN secret is not set"
109-
exit 1
110-
fi
111-
echo "Using main channel: $CHANNEL_ID"
112-
elif [[ "$BRANCH_NAME" =~ ^test/ ]]; then
113-
CHANNEL_ID="${{ secrets.SMARTTHINGS_CHANNEL_ID_TEST }}"
114-
if [[ -z "$CHANNEL_ID" ]]; then
115-
echo "ERROR: SMARTTHINGS_CHANNEL_ID_TEST secret is not set"
116-
exit 1
117-
fi
118-
echo "Using test channel: $CHANNEL_ID"
119-
else
120-
echo "ERROR: Unknown branch pattern: $BRANCH_NAME"
121-
echo "Expected branch: main or test/*"
122-
exit 1
123-
fi
124-
125-
echo "channel_id=$CHANNEL_ID" >> $GITHUB_OUTPUT
126-
127-
- name: Package and deploy drivers
128-
run: |
129-
IFS=',' read -ra FOLDERS <<< "${{ steps.find-drivers.outputs.folders }}"
130-
131-
CHANNEL_ID="${{ steps.channel.outputs.channel_id }}"
132-
echo "Using channel: $CHANNEL_ID"
133-
134-
for folder in "${FOLDERS[@]}"; do
135-
echo "Processing driver: $folder"
136-
137-
# Package driver
138-
echo "Packaging driver in $folder..."
139-
if ! smartthings edge:drivers:package "$folder" 2>&1; then
140-
echo "ERROR: Failed to package driver $folder"
141-
continue
142-
fi
143-
144-
# Get package key and name from config.yml
145-
PACKAGE_KEY=$(grep -E "^packageKey:" "${folder}config.yml" | sed 's/packageKey:[[:space:]]*//' | tr -d "'\"")
146-
DRIVER_NAME=$(grep -E "^name:" "${folder}config.yml" | sed 's/name:[[:space:]]*//' | tr -d "'\"")
147-
148-
echo "Looking for driver with packageKey: $PACKAGE_KEY or name: $DRIVER_NAME"
149-
150-
# Find driver ID by packageKey or name
151-
DRIVER_ID=$(smartthings edge:drivers --json 2>/dev/null | jq -r --arg pk "$PACKAGE_KEY" --arg name "$DRIVER_NAME" '.[] | select(.packageKey == $pk or .name == $name) | .driverId' 2>/dev/null | head -n1)
152-
153-
if [[ -z "$DRIVER_ID" || "$DRIVER_ID" == "null" ]]; then
154-
echo "WARNING: Driver not found in existing drivers list"
155-
echo "Note: If this is the first deployment, you may need to create the driver manually first"
156-
echo "Skipping driver assignment for $folder"
157-
continue
158-
fi
159-
160-
echo "Found existing driver: $DRIVER_ID"
161-
162-
# Assign driver to channel
163-
echo "Assigning driver $DRIVER_ID to channel $CHANNEL_ID..."
164-
if ! smartthings edge:channels:assign --channel "$CHANNEL_ID" "$DRIVER_ID" 2>&1; then
165-
echo "ERROR: Failed to assign driver $DRIVER_ID to channel $CHANNEL_ID"
166-
continue
167-
fi
168-
169-
echo "Successfully deployed driver: $folder"
170-
done
171-
172-
- name: Deployment summary
173-
run: |
174-
echo "## Deployment Summary" >> $GITHUB_STEP_SUMMARY
175-
echo "" >> $GITHUB_STEP_SUMMARY
176-
echo "✅ All drivers have been processed" >> $GITHUB_STEP_SUMMARY
177-
echo "" >> $GITHUB_STEP_SUMMARY
178-
echo "### Deployed Drivers:" >> $GITHUB_STEP_SUMMARY
179-
IFS=',' read -ra FOLDERS <<< "${{ steps.find-drivers.outputs.folders }}"
180-
for folder in "${FOLDERS[@]}"; do
181-
echo "- $(basename "$folder")" >> $GITHUB_STEP_SUMMARY
182-
done
20+
deploy:
21+
runs-on: ubuntu-latest
22+
23+
steps:
24+
- name: Checkout code
25+
uses: actions/checkout@v4
26+
27+
- name: Setup Node.js
28+
uses: actions/setup-node@v4
29+
with:
30+
node-version: "20"
31+
32+
- name: Install SmartThings CLI
33+
run: |
34+
npm install -g @smartthings/cli@latest
35+
36+
- name: Authenticate SmartThings CLI
37+
run: |
38+
smartthings auth --token "${{ secrets.SMARTTHINGS_PERSONAL_ACCESS_TOKEN }}"
39+
40+
- name: Setup dependencies
41+
run: |
42+
sudo apt-get update
43+
sudo apt-get install -y jq
44+
45+
- name: Find driver folders
46+
id: find-drivers
47+
run: |
48+
DRIVER_FOLDERS=()
49+
for dir in */; do
50+
if [[ -d "${dir}profiles" && -d "${dir}src" && -f "${dir}config.yml" ]]; then
51+
DRIVER_FOLDERS+=("$dir")
52+
fi
53+
done
54+
echo "folders=$(IFS=','; echo "${DRIVER_FOLDERS[*]}")" >> $GITHUB_OUTPUT
55+
echo "Found driver folders: ${DRIVER_FOLDERS[@]}"
56+
57+
- name: Update device profiles
58+
run: |
59+
IFS=',' read -ra FOLDERS <<< "${{ steps.find-drivers.outputs.folders }}"
60+
for folder in "${FOLDERS[@]}"; do
61+
echo "Processing profiles for: $folder"
62+
PROFILE_DIR="${folder}profiles"
63+
64+
if [[ ! -d "$PROFILE_DIR" ]]; then
65+
echo "Profile directory not found: $PROFILE_DIR"
66+
continue
67+
fi
68+
69+
shopt -s nullglob
70+
files=("$PROFILE_DIR"/*.yml)
71+
shopt -u nullglob
72+
73+
if [[ ${#files[@]} -eq 0 ]]; then
74+
echo "No YAML files found in $PROFILE_DIR"
75+
continue
76+
fi
77+
78+
for file in "${files[@]}"; do
79+
PROFILE_NAME=$(basename "$file" .yml)
80+
echo "Processing profile: $PROFILE_NAME"
81+
82+
PROFILE_ID=$(smartthings deviceprofiles --json 2>/dev/null | jq -r '.[] | select(.name=="'"$PROFILE_NAME"'") | .id' 2>/dev/null || echo "")
83+
84+
if [[ -n "$PROFILE_ID" && "$PROFILE_ID" != "null" ]]; then
85+
echo "Deleting existing profile: $PROFILE_NAME ($PROFILE_ID)"
86+
smartthings deviceprofiles:delete "$PROFILE_ID" >/dev/null 2>&1 || true
87+
fi
88+
89+
echo "Creating profile from file: $file"
90+
if ! smartthings deviceprofiles:create --input "$file" 2>&1; then
91+
echo "ERROR: Failed to create profile $PROFILE_NAME"
92+
continue
93+
fi
94+
95+
NEW_ID=$(smartthings deviceprofiles --json 2>/dev/null | jq -r '.[] | select(.name=="'"$PROFILE_NAME"'") | .id' 2>/dev/null || echo "")
96+
if [[ -z "$NEW_ID" || "$NEW_ID" == "null" ]]; then
97+
echo "ERROR: Failed to find created profile $PROFILE_NAME"
98+
continue
99+
fi
100+
101+
echo "Publishing profile: $PROFILE_NAME ($NEW_ID)"
102+
if ! smartthings deviceprofiles:publish "$NEW_ID" 2>&1; then
103+
echo "ERROR: Failed to publish profile $PROFILE_NAME"
104+
continue
105+
fi
106+
done
107+
done
108+
109+
- name: Determine channel ID
110+
id: channel
111+
run: |
112+
# workflow_dispatch로 수동 실행된 경우 입력값 사용, push 이벤트인 경우 브랜치 이름 사용
113+
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
114+
BRANCH_TYPE="${{ github.event.inputs.branch_type }}"
115+
echo "Manual workflow dispatch with branch_type: $BRANCH_TYPE"
116+
117+
if [[ "$BRANCH_TYPE" == "main" ]]; then
118+
CHANNEL_ID="${{ secrets.SMARTTHINGS_CHANNEL_ID_MAIN }}"
119+
if [[ -z "$CHANNEL_ID" ]]; then
120+
echo "ERROR: SMARTTHINGS_CHANNEL_ID_MAIN secret is not set"
121+
exit 1
122+
fi
123+
echo "Using main channel: $CHANNEL_ID"
124+
elif [[ "$BRANCH_TYPE" == "test" ]]; then
125+
CHANNEL_ID="${{ secrets.SMARTTHINGS_CHANNEL_ID_TEST }}"
126+
if [[ -z "$CHANNEL_ID" ]]; then
127+
echo "ERROR: SMARTTHINGS_CHANNEL_ID_TEST secret is not set"
128+
exit 1
129+
fi
130+
echo "Using test channel: $CHANNEL_ID"
131+
else
132+
echo "ERROR: Unknown branch_type: $BRANCH_TYPE"
133+
exit 1
134+
fi
135+
else
136+
BRANCH_NAME="${{ github.ref_name }}"
137+
echo "Automatic push event on branch: $BRANCH_NAME"
138+
139+
if [[ "$BRANCH_NAME" == "main" ]]; then
140+
CHANNEL_ID="${{ secrets.SMARTTHINGS_CHANNEL_ID_MAIN }}"
141+
if [[ -z "$CHANNEL_ID" ]]; then
142+
echo "ERROR: SMARTTHINGS_CHANNEL_ID_MAIN secret is not set"
143+
exit 1
144+
fi
145+
echo "Using main channel: $CHANNEL_ID"
146+
elif [[ "$BRANCH_NAME" =~ ^test/ ]]; then
147+
CHANNEL_ID="${{ secrets.SMARTTHINGS_CHANNEL_ID_TEST }}"
148+
if [[ -z "$CHANNEL_ID" ]]; then
149+
echo "ERROR: SMARTTHINGS_CHANNEL_ID_TEST secret is not set"
150+
exit 1
151+
fi
152+
echo "Using test channel: $CHANNEL_ID"
153+
else
154+
echo "ERROR: Unknown branch pattern: $BRANCH_NAME"
155+
echo "Expected branch: main or test/*"
156+
exit 1
157+
fi
158+
fi
159+
160+
echo "channel_id=$CHANNEL_ID" >> $GITHUB_OUTPUT
161+
162+
- name: Package and deploy drivers
163+
run: |
164+
IFS=',' read -ra FOLDERS <<< "${{ steps.find-drivers.outputs.folders }}"
165+
166+
CHANNEL_ID="${{ steps.channel.outputs.channel_id }}"
167+
echo "Using channel: $CHANNEL_ID"
168+
169+
for folder in "${FOLDERS[@]}"; do
170+
echo "Processing driver: $folder"
171+
172+
# Package driver
173+
echo "Packaging driver in $folder..."
174+
if ! smartthings edge:drivers:package "$folder" 2>&1; then
175+
echo "ERROR: Failed to package driver $folder"
176+
continue
177+
fi
178+
179+
# Get package key and name from config.yml
180+
PACKAGE_KEY=$(grep -E "^packageKey:" "${folder}config.yml" | sed 's/packageKey:[[:space:]]*//' | tr -d "'\"")
181+
DRIVER_NAME=$(grep -E "^name:" "${folder}config.yml" | sed 's/name:[[:space:]]*//' | tr -d "'\"")
182+
183+
echo "Looking for driver with packageKey: $PACKAGE_KEY or name: $DRIVER_NAME"
184+
185+
# Find driver ID by packageKey or name
186+
DRIVER_ID=$(smartthings edge:drivers --json 2>/dev/null | jq -r --arg pk "$PACKAGE_KEY" --arg name "$DRIVER_NAME" '.[] | select(.packageKey == $pk or .name == $name) | .driverId' 2>/dev/null | head -n1)
187+
188+
if [[ -z "$DRIVER_ID" || "$DRIVER_ID" == "null" ]]; then
189+
echo "WARNING: Driver not found in existing drivers list"
190+
echo "Note: If this is the first deployment, you may need to create the driver manually first"
191+
echo "Skipping driver assignment for $folder"
192+
continue
193+
fi
194+
195+
echo "Found existing driver: $DRIVER_ID"
196+
197+
# Assign driver to channel
198+
echo "Assigning driver $DRIVER_ID to channel $CHANNEL_ID..."
199+
if ! smartthings edge:channels:assign --channel "$CHANNEL_ID" "$DRIVER_ID" 2>&1; then
200+
echo "ERROR: Failed to assign driver $DRIVER_ID to channel $CHANNEL_ID"
201+
continue
202+
fi
203+
204+
echo "Successfully deployed driver: $folder"
205+
done
206+
207+
- name: Deployment summary
208+
run: |
209+
echo "## Deployment Summary" >> $GITHUB_STEP_SUMMARY
210+
echo "" >> $GITHUB_STEP_SUMMARY
211+
echo "✅ All drivers have been processed" >> $GITHUB_STEP_SUMMARY
212+
echo "" >> $GITHUB_STEP_SUMMARY
213+
echo "### Deployed Drivers:" >> $GITHUB_STEP_SUMMARY
214+
IFS=',' read -ra FOLDERS <<< "${{ steps.find-drivers.outputs.folders }}"
215+
for folder in "${FOLDERS[@]}"; do
216+
echo "- $(basename "$folder")" >> $GITHUB_STEP_SUMMARY
217+
done

0 commit comments

Comments
 (0)