-
Notifications
You must be signed in to change notification settings - Fork 550
145 lines (138 loc) · 6.51 KB
/
telegram-publish-files.yml
File metadata and controls
145 lines (138 loc) · 6.51 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
name: Telegram publish release files
# Posts every release artifact (Android APKs, Windows ZIP, macOS, Linux,
# OpenWRT, Raspbian) to the Telegram channel as individual messages with
# Persian captions and a #v<MAJOR><MINOR><PATCH> hashtag. Files larger
# than the bot API's 50 MB ceiling are split into ~45 MB byte chunks
# server-side and posted as `<name>.part_aa`, `.part_ab`, ... — recipients
# reassemble with `cat <name>.part_* > <name>`.
#
# This workflow is decoupled from `release.yml` so it can be re-triggered
# for any historical tag (e.g. to re-post v1.8.0 after a Telegram channel
# wipe) without rebuilding artifacts. It downloads from the GitHub Release
# page directly via `gh release download`, so the assets must already
# exist there.
on:
workflow_dispatch:
inputs:
version:
description: 'Release tag to publish (with or without the v prefix, e.g. 1.8.0 or v1.8.0)'
required: true
type: string
# Auto-trigger after a successful `release` workflow run. Posts files
# to Telegram once the release page exists. The `head_branch` of the
# triggering run is the tag name (e.g. `v1.8.0`) on tag-pushed releases,
# which is what we feed `gh release download`.
workflow_run:
workflows: [release]
types: [completed]
permissions:
contents: read
jobs:
publish:
# Skip when triggered by a `release` run that didn't succeed — no
# point posting half a release. Manual `workflow_dispatch` always
# runs (the user explicitly asked for it).
if: |
github.event_name == 'workflow_dispatch'
|| github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# Sparse checkout would be nicer but stock checkout is fast
# enough for a 5 MB workflow file + ~200 KB script.
fetch-depth: 1
- name: Resolve version + hashtag
id: ver
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
if [ -n "${{ inputs.version || '' }}" ]; then
VER="${{ inputs.version }}"
else
# workflow_run path. `head_branch` for a tag-pushed release
# workflow is the tag name (e.g. `v1.8.0`).
VER="${{ github.event.workflow_run.head_branch || '' }}"
fi
if [ -z "$VER" ]; then
echo "::error::could not determine version from inputs or workflow_run trigger"
exit 1
fi
# Strip the leading `v` if present.
VER="${VER#v}"
# Hashtag: `#v` + version with dots removed. So 1.8.0 → #v180,
# 1.8.10 → #v1810, 2.0.0 → #v200. Predictable across releases.
HASHTAG="#v$(echo "$VER" | tr -d '.')"
echo "version=$VER" >> "$GITHUB_OUTPUT"
echo "hashtag=$HASHTAG" >> "$GITHUB_OUTPUT"
echo "Resolved: version=$VER hashtag=$HASHTAG"
- name: Download release assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
mkdir -p assets
# Mirror the retry pattern from `release.yml`'s download step —
# GitHub's release-asset CDN occasionally times out on cold
# tags. Three attempts with 30 s backoff covers most flakes.
#
# `--clobber` overwrites any partial files left behind by a
# previous failed attempt — without it, attempt 2/3 would error
# with "already exists" the moment any single asset finished
# downloading on attempt 1 before the CDN timed out (the v1.9.2
# publish hit exactly this — HTTP 500 mid-download, then attempts
# 2/3 failed on "already exists" for the assets that did finish).
for attempt in 1 2 3; do
if gh release download "v${{ steps.ver.outputs.version }}" \
--dir assets \
--clobber \
--repo "${GITHUB_REPOSITORY}"; then
echo "downloaded release assets on attempt $attempt"
ls -la assets/
exit 0
fi
echo "attempt $attempt failed; retrying in 30s..."
sleep 30
done
echo "::error::failed to download release assets after 3 attempts"
exit 1
- name: Publish files to Telegram channel
env:
BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
# The files channel — supergroup-style negative ID, hard-coded
# rather than templated as a repo variable because there's only
# ever one of these and putting it in source makes the workflow
# auditable. The bot token already has post permissions there.
CHAT_ID: '-1003966234444'
# The main announcement channel. Receives a single cross-link
# message per release pointing at the file-channel anchor post,
# instead of the previous behaviour of attaching the universal
# APK + full changelog. Sourced from the same secret the
# legacy `telegram` job in release.yml used.
MAIN_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
# Public-username form of the files channel link. Used for
# both (a) the post-link in the main-channel cross-post — so
# `t.me/<name>/<msg>` works for everyone, not just members
# via `t.me/c/<id>/<msg>` — and (b) one of the two
# channel-join links rendered at the bottom of the cross-post.
# Defaults to `mhrv_rs` (current public username); override via
# repo variable if the channel is renamed.
FILES_CHANNEL_USERNAME: ${{ vars.FILES_CHANNEL_USERNAME || 'mhrv_rs' }}
# `t.me/+<hash>` invite link for the files channel. Rendered
# as the second channel-join option in the main-channel
# cross-post — the only join path that works for users coming
# from outside Telegram search (private/restricted channels)
# or whose Telegram client doesn't resolve usernames cleanly.
# Override via repo variable if the channel's invite hash is
# rotated.
FILES_CHANNEL_INVITE: ${{ vars.FILES_CHANNEL_INVITE || 'https://t.me/+R1OyoHX2boA1ZDgx' }}
run: |
if [ -z "${BOT_TOKEN:-}" ]; then
echo "::error::TELEGRAM_BOT_TOKEN not set; can't publish"
exit 1
fi
python3 .github/scripts/telegram_publish_files.py \
--assets-dir assets \
--version "${{ steps.ver.outputs.version }}" \
--hashtag "${{ steps.ver.outputs.hashtag }}"