Skip to content

Commit 4ab29d3

Browse files
Tighten gist CTA markdown formatting
1 parent d724bfb commit 4ab29d3

1 file changed

Lines changed: 0 additions & 261 deletions

File tree

Lines changed: 0 additions & 261 deletions
Original file line numberDiff line numberDiff line change
@@ -1,261 +0,0 @@
1-
name: Create README Gist
2-
3-
on:
4-
workflow_dispatch:
5-
inputs:
6-
repository:
7-
description: "Repo name in the serpgames org, or serpgames/repo"
8-
required: true
9-
type: string
10-
ref:
11-
description: "Branch, tag, or SHA to read from. Leave blank to use the repo default branch."
12-
required: false
13-
default: ""
14-
type: string
15-
public:
16-
description: "Create a public gist"
17-
required: false
18-
default: true
19-
type: boolean
20-
gist_description:
21-
description: "Optional gist title/description. Defaults to the README H1."
22-
required: false
23-
default: ""
24-
type: string
25-
gist_id:
26-
description: "Optional existing gist ID or URL to update instead of creating a new gist."
27-
required: false
28-
default: ""
29-
type: string
30-
workflow_call:
31-
inputs:
32-
repository:
33-
description: "Repo name in the serpgames org, or serpgames/repo"
34-
required: true
35-
type: string
36-
ref:
37-
description: "Branch, tag, or SHA to read from. Leave blank to use the repo default branch."
38-
required: false
39-
default: ""
40-
type: string
41-
public:
42-
description: "Create a public gist"
43-
required: false
44-
default: true
45-
type: boolean
46-
gist_description:
47-
description: "Optional gist title/description. Defaults to the README H1."
48-
required: false
49-
default: ""
50-
type: string
51-
gist_id:
52-
description: "Optional existing gist ID or URL to update instead of creating a new gist."
53-
required: false
54-
default: ""
55-
type: string
56-
secrets:
57-
SERPGAMEDEVELOPER_GIST_TOKEN:
58-
description: "PAT from the serpgamedeveloper account with gist write permission"
59-
required: true
60-
outputs:
61-
gist_url:
62-
description: "Created or updated gist URL"
63-
value: ${{ jobs.create-readme-gist.outputs.gist_url }}
64-
gist_id:
65-
description: "Created or updated gist ID"
66-
value: ${{ jobs.create-readme-gist.outputs.gist_id }}
67-
68-
permissions:
69-
contents: read
70-
71-
jobs:
72-
create-readme-gist:
73-
name: Create README gist
74-
runs-on: ubuntu-latest
75-
outputs:
76-
gist_url: ${{ steps.create.outputs.gist_url }}
77-
gist_id: ${{ steps.create.outputs.gist_id }}
78-
steps:
79-
- name: Create gist from repository README
80-
id: create
81-
shell: bash
82-
env:
83-
INPUT_REPOSITORY: ${{ inputs.repository }}
84-
INPUT_REF: ${{ inputs.ref }}
85-
GIST_PUBLIC: ${{ inputs.public }}
86-
GIST_DESCRIPTION: ${{ inputs.gist_description }}
87-
INPUT_GIST_ID: ${{ inputs.gist_id }}
88-
GITHUB_TOKEN: ${{ github.token }}
89-
SERPGAMEDEVELOPER_GIST_TOKEN: ${{ secrets.SERPGAMEDEVELOPER_GIST_TOKEN }}
90-
run: |
91-
node <<'NODE'
92-
const fs = require("fs");
93-
94-
async function main() {
95-
const apiVersion = "2022-11-28";
96-
const readToken = process.env.GITHUB_TOKEN || "";
97-
const gistToken = process.env.SERPGAMEDEVELOPER_GIST_TOKEN || "";
98-
99-
if (!gistToken) {
100-
throw new Error("Missing SERPGAMEDEVELOPER_GIST_TOKEN secret. Add a serpgamedeveloper PAT with gist write permission.");
101-
}
102-
103-
const rawRepository = (process.env.INPUT_REPOSITORY || "").trim();
104-
if (!rawRepository) {
105-
throw new Error("The repository input is required.");
106-
}
107-
108-
const parts = rawRepository.includes("/")
109-
? rawRepository.split("/")
110-
: ["serpgames", rawRepository];
111-
112-
if (parts.length !== 2 || parts[0] !== "serpgames") {
113-
throw new Error("repository must be a repo name in serpgames, or serpgames/repo-name.");
114-
}
115-
116-
const [owner, repo] = parts;
117-
if (!/^[A-Za-z0-9_.-]+$/.test(repo)) {
118-
throw new Error(`Invalid repository name: ${repo}`);
119-
}
120-
121-
const githubHeaders = {
122-
"Accept": "application/vnd.github+json",
123-
"X-GitHub-Api-Version": apiVersion,
124-
"User-Agent": "serpgames-readme-gist-action",
125-
};
126-
if (readToken) {
127-
githubHeaders.Authorization = `Bearer ${readToken}`;
128-
}
129-
130-
async function requestJson(url, options = {}) {
131-
const response = await fetch(url, {
132-
...options,
133-
headers: {
134-
...githubHeaders,
135-
...(options.headers || {}),
136-
},
137-
});
138-
const text = await response.text();
139-
let body = null;
140-
if (text) {
141-
try {
142-
body = JSON.parse(text);
143-
} catch {
144-
body = text;
145-
}
146-
}
147-
if (!response.ok) {
148-
const details = typeof body === "string" ? body : JSON.stringify(body);
149-
throw new Error(`GitHub API request failed: ${response.status} ${response.statusText} ${url} ${details}`);
150-
}
151-
return body;
152-
}
153-
154-
function cleanReadmeForGist(markdown) {
155-
return markdown
156-
.replace(/\r\n/g, "\n")
157-
.replace(/\\n/g, "\n")
158-
.replace(/^\[!\[START GAME\]\(\.\/start-game\.(?:gif|svg)\)\]\(([^)]+)\)\s*$/m, "**[START GAME]($1)**")
159-
.trimEnd() + "\n";
160-
}
161-
162-
function readTitle(markdown, fallback) {
163-
const h1 = markdown.match(/^#\s+(.+?)\s*$/m);
164-
return h1 ? h1[1].trim() : fallback;
165-
}
166-
167-
function normalizeGistId(input) {
168-
const value = (input || "").trim();
169-
if (!value) return "";
170-
const match = value.match(/([0-9a-f]{20,})$/i);
171-
return match ? match[1] : value;
172-
}
173-
174-
const repoInfo = await requestJson(`https://api.github.com/repos/${owner}/${repo}`);
175-
const requestedRef = (process.env.INPUT_REF || "").trim();
176-
const ref = requestedRef || repoInfo.default_branch;
177-
const readme = await requestJson(
178-
`https://api.github.com/repos/${owner}/${repo}/readme?ref=${encodeURIComponent(ref)}`
179-
);
180-
181-
if (readme.encoding !== "base64") {
182-
throw new Error(`Unsupported README encoding: ${readme.encoding}`);
183-
}
184-
185-
const rawReadmeMarkdown = Buffer.from(readme.content.replace(/\n/g, ""), "base64").toString("utf8");
186-
const readmeMarkdown = cleanReadmeForGist(rawReadmeMarkdown);
187-
const title = (process.env.GIST_DESCRIPTION || "").trim()
188-
|| readTitle(readmeMarkdown, `Play ${repo.replace(/-game$/, "").replace(/-/g, " ")} Game Online - Free Unblocked`);
189-
const gistPublic = String(process.env.GIST_PUBLIC || "true").toLowerCase() !== "false";
190-
const existingGistId = normalizeGistId(process.env.INPUT_GIST_ID);
191-
192-
let gist;
193-
if (existingGistId) {
194-
const existingGist = await requestJson(`https://api.github.com/gists/${existingGistId}`, {
195-
headers: {
196-
Authorization: `Bearer ${gistToken}`,
197-
},
198-
});
199-
const files = {};
200-
for (const filename of Object.keys(existingGist.files || {})) {
201-
files[filename] = null;
202-
}
203-
const firstMarkdownFile = Object.keys(existingGist.files || {}).find((filename) => filename.toLowerCase().endsWith(".md"));
204-
files[firstMarkdownFile || "README.md"] = {
205-
filename: "README.md",
206-
content: readmeMarkdown,
207-
};
208-
gist = await requestJson(`https://api.github.com/gists/${existingGistId}`, {
209-
method: "PATCH",
210-
headers: {
211-
Authorization: `Bearer ${gistToken}`,
212-
},
213-
body: JSON.stringify({
214-
description: title,
215-
files,
216-
}),
217-
});
218-
} else {
219-
gist = await requestJson("https://api.github.com/gists", {
220-
method: "POST",
221-
headers: {
222-
Authorization: `Bearer ${gistToken}`,
223-
},
224-
body: JSON.stringify({
225-
description: title,
226-
public: gistPublic,
227-
files: {
228-
"README.md": {
229-
content: readmeMarkdown,
230-
},
231-
},
232-
}),
233-
});
234-
}
235-
236-
fs.appendFileSync(process.env.GITHUB_OUTPUT, `gist_url=${gist.html_url}\n`);
237-
fs.appendFileSync(process.env.GITHUB_OUTPUT, `gist_id=${gist.id}\n`);
238-
239-
if (process.env.GITHUB_STEP_SUMMARY) {
240-
fs.appendFileSync(
241-
process.env.GITHUB_STEP_SUMMARY,
242-
[
243-
existingGistId ? "## README gist updated" : "## README gist created",
244-
"",
245-
`- Title: ${title}`,
246-
`- Repository: ${owner}/${repo}`,
247-
`- Ref: ${ref}`,
248-
`- README: ${readme.html_url}`,
249-
`- Gist: ${gist.html_url}`,
250-
`- Public: ${gist.public}`,
251-
"",
252-
].join("\n")
253-
);
254-
}
255-
}
256-
257-
main().catch((error) => {
258-
console.error(error);
259-
process.exit(1);
260-
});
261-
NODE

0 commit comments

Comments
 (0)