forked from GULBILBOT/gul-bil-bluesky
-
Notifications
You must be signed in to change notification settings - Fork 0
175 lines (141 loc) · 6.42 KB
/
Copy pathupdate-sun-schedule.yml
File metadata and controls
175 lines (141 loc) · 6.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
name: "Update Sun Schedule"
on:
schedule:
# Run once daily at 02:00 UTC (3 AM Oslo time in winter)
- cron: "0 2 * * *"
workflow_dispatch: # Manual trigger for testing
jobs:
update-schedule:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.PAT_TOKEN }}
- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requests PyYAML
- name: Fetch sun times and update schedule
run: |
python3 << 'EOF'
import json
import requests
from datetime import datetime, time
# Load configuration
with open('config.json', 'r') as f:
config = json.load(f)
# Fetch sun times
LAT = config['location']['latitude']
LNG = config['location']['longitude']
url = config['api']['sunrise_sunset_url'].format(lat=LAT, lng=LNG)
response = requests.get(url, timeout=15)
response.raise_for_status()
data = response.json()
if data.get("status") != "OK":
raise Exception(f"API returned status: {data.get('status')}")
results = data["results"]
# Parse times (ISO format from API when formatted=0)
def parse_time(time_str):
"""Extract hour and minute from ISO datetime string"""
dt = datetime.fromisoformat(time_str.replace('Z', '+00:00'))
return dt.hour, dt.minute
# Get astronomical twilight times (darkest)
twilight_end_h, twilight_end_m = parse_time(results["astronomical_twilight_end"])
twilight_begin_h, twilight_begin_m = parse_time(results["astronomical_twilight_begin"])
# Generate cron schedule for dark hours
# Run every 15 minutes during astronomical darkness
# Cron format: minute hour * * *
# If twilight_end is 17:44:59 (5:44 PM), start at 18:00
# If twilight_begin is 4:18:25 AM, end at 4:00 AM
start_hour = twilight_end_h + 1 if twilight_end_m > 30 else twilight_end_h
end_hour = twilight_begin_h
# Handle case where darkness spans midnight
if start_hour >= end_hour:
# Example: 18:00-23:59 and 00:00-04:00
cron_evening = f"*/15 {start_hour}-23 * * *"
cron_morning = f"*/15 0-{end_hour} * * *" if end_hour > 0 else None
cron_schedule = [cron_evening]
if cron_morning:
cron_schedule.append(cron_morning)
else:
# Continuous dark period (rare in Lommedalen)
cron_schedule = [f"*/15 {start_hour}-{end_hour} * * *"]
# Save schedule info
schedule_info = {
"updated_at": datetime.utcnow().isoformat() + "Z",
"location": config['location'],
"sun_times": results,
"dark_hours": {
"start_hour": start_hour,
"end_hour": end_hour,
"spans_midnight": start_hour >= end_hour
},
"cron_schedules": cron_schedule
}
schedule_file = config['data']['sun_schedule_file']
with open(schedule_file, 'w') as f:
json.dump(schedule_info, f, indent=2)
print(f"✅ Updated sun schedule")
print(f" Astronomical darkness: {start_hour}:00 - {end_hour}:00 UTC")
print(f" Cron schedules: {', '.join(cron_schedule)}")
EOF
- name: Update workflow schedule
run: |
python3 << 'EOF'
import json
import re
# Load config
with open('config.json', 'r') as f:
config = json.load(f)
# Load schedule info
schedule_file = config['data']['sun_schedule_file']
with open(schedule_file, 'r') as f:
schedule_info = json.load(f)
cron_schedules = schedule_info['cron_schedules']
# Read the workflow file
with open('.github/workflows/post.yml', 'r') as f:
content = f.read()
# Find and replace the schedule section using regex
# This preserves comments and formatting
schedule_pattern = r'(on:\s*\n\s+schedule:\s*\n(?:\s+#[^\n]*\n)*)((?:\s+-\s+cron:\s+[^\n]+\n)+)'
# Build new schedule lines
new_schedule_lines = []
for cron in cron_schedules:
new_schedule_lines.append(f' - cron: "{cron}"\n')
new_schedule_section = ''.join(new_schedule_lines)
# Replace the schedule section
def replacer(match):
return match.group(1) + new_schedule_section
updated_content = re.sub(schedule_pattern, replacer, content)
# Write back
with open('.github/workflows/post.yml', 'w') as f:
f.write(updated_content)
print(f"✅ Updated post.yml with {len(cron_schedules)} cron schedule(s)")
print(f" Schedules: {', '.join(cron_schedules)}")
EOF
- name: Commit and push changes
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Get schedule file from config
SCHEDULE_FILE=$(jq -r '.data.sun_schedule_file' config.json)
git add "$SCHEDULE_FILE" .github/workflows/post.yml
if git diff --staged --quiet; then
echo "No changes to commit"
else
START_HOUR=$(jq -r '.dark_hours.start_hour' "$SCHEDULE_FILE")
END_HOUR=$(jq -r '.dark_hours.end_hour' "$SCHEDULE_FILE")
UPDATED_AT=$(jq -r '.updated_at' "$SCHEDULE_FILE")
CRON_SCHEDULES=$(jq -r '.cron_schedules | join(", ")' "$SCHEDULE_FILE")
git commit -m "chore: update sun schedule and workflow timing [automated]" \
-m "Dark hours: ${START_HOUR}:00 - ${END_HOUR}:00 UTC" \
-m "Cron: ${CRON_SCHEDULES}" \
-m "Updated: ${UPDATED_AT}"
git push
fi