Compare commits
2
Commits
86c2f91c7a
...
7bbe53b886
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7bbe53b886 | ||
|
|
355bf84ec7 |
@@ -0,0 +1,149 @@
|
|||||||
|
# Prompt: automatyczne wdrażanie aplikacji do Cloudflare Pages
|
||||||
|
|
||||||
|
Chcę przygotować i wdrożyć tę aplikację webową do Cloudflare Pages.
|
||||||
|
|
||||||
|
Pracuj bez GitHuba — użyj lokalnego repozytorium Git oraz Wrangler CLI.
|
||||||
|
|
||||||
|
## Wymagania
|
||||||
|
|
||||||
|
1. Przeanalizuj projekt i ustal:
|
||||||
|
- gdzie znajduje się główny plik aplikacji,
|
||||||
|
- jakie pliki są potrzebne do uruchomienia strony,
|
||||||
|
- czy projekt ma repozytorium Git,
|
||||||
|
- jaki jest aktualny remote Git,
|
||||||
|
- czy istnieje folder przeznaczony do publikacji.
|
||||||
|
|
||||||
|
2. Przygotuj folder wdrożeniowy, np. `wersja1` albo `dist`.
|
||||||
|
|
||||||
|
Folder powinien zawierać wyłącznie pliki potrzebne do działania aplikacji:
|
||||||
|
- `index.html`,
|
||||||
|
- pliki CSS,
|
||||||
|
- pliki JavaScript,
|
||||||
|
- pliki CSV/JSON,
|
||||||
|
- obrazy i inne używane zasoby.
|
||||||
|
|
||||||
|
3. Jeśli aplikacja korzysta z plików znajdujących się poza folderem wdrożeniowym, przygotuj synchronizację. Przed każdym wdrożeniem kopiuj aktualne pliki źródłowe do folderu publikacji, aby lokalna i opublikowana wersja nie różniły się.
|
||||||
|
|
||||||
|
4. Skonfiguruj Cloudflare Pages przez Wrangler:
|
||||||
|
- bez GitHuba,
|
||||||
|
- bez GitHub Actions,
|
||||||
|
- użyj istniejącego projektu Pages, jeśli istnieje,
|
||||||
|
- jeśli projekt nie istnieje, przygotuj polecenie jego utworzenia.
|
||||||
|
|
||||||
|
5. Przygotuj skrypt `deploy-cloudflare.ps1`, który:
|
||||||
|
- wskazuje folder wdrożeniowy,
|
||||||
|
- synchronizuje pliki źródłowe,
|
||||||
|
- używa `wrangler.cmd`, a nie `wrangler.ps1`,
|
||||||
|
- działa przy zablokowanej polityce wykonywania skryptów PowerShell,
|
||||||
|
- automatycznie dodaje `C:\Program Files\nodejs` do PATH, jeśli Node.js jest zainstalowany,
|
||||||
|
- pobiera nazwę projektu Cloudflare z lokalnej konfiguracji Git,
|
||||||
|
- obsługuje opcjonalny Cloudflare Account ID,
|
||||||
|
- jasno zgłasza błędy.
|
||||||
|
|
||||||
|
6. Nie zapisuj tokenów Cloudflare w kodzie ani w repozytorium.
|
||||||
|
|
||||||
|
Logowanie powinno używać:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
& "$env:APPDATA\npm\wrangler.cmd" login
|
||||||
|
```
|
||||||
|
|
||||||
|
Jeśli Node.js lub Wrangler nie są dostępne:
|
||||||
|
- sprawdź instalację Node.js,
|
||||||
|
- zainstaluj Node.js LTS,
|
||||||
|
- zainstaluj Wrangler,
|
||||||
|
- sprawdź działanie poleceniem:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
& "$env:APPDATA\npm\wrangler.cmd" --version
|
||||||
|
```
|
||||||
|
|
||||||
|
7. Przygotuj instalator `install-cloudflare-hook.ps1`, który:
|
||||||
|
- instaluje hook w `.git/hooks`,
|
||||||
|
- ustawia lokalne `core.hooksPath`,
|
||||||
|
- nadaje hookowi prawa wykonywania,
|
||||||
|
- działa na Windows,
|
||||||
|
- uruchamia wdrożenie automatycznie przed każdym `git push`.
|
||||||
|
|
||||||
|
Użyj hooka `pre-push`, ponieważ `post-push` może nie być wykonywany poprawnie przez Git for Windows.
|
||||||
|
|
||||||
|
8. Przygotuj plik `hooks/pre-push`, który:
|
||||||
|
- uruchamia `deploy-cloudflare.ps1`,
|
||||||
|
- zatrzymuje push, jeśli wdrożenie się nie powiedzie,
|
||||||
|
- wyświetla komunikaty:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Cloudflare Pages: wdrażanie przed pushem…
|
||||||
|
Cloudflare Pages: wdrożenie zakończone
|
||||||
|
```
|
||||||
|
|
||||||
|
9. Przygotuj instrukcję uruchomienia:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Set-Location "ŚCIEŻKA_DO_PROJEKTU"
|
||||||
|
```
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
& "$env:APPDATA\npm\wrangler.cmd" login
|
||||||
|
```
|
||||||
|
|
||||||
|
Sprawdź projekty:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
& "$env:APPDATA\npm\wrangler.cmd" pages project list --json
|
||||||
|
```
|
||||||
|
|
||||||
|
Ustaw nazwę projektu:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git config --local cloudflare.pagesProject "NAZWA_PROJEKTU"
|
||||||
|
```
|
||||||
|
|
||||||
|
Opcjonalnie ustaw Account ID:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git config --local cloudflare.accountId "ACCOUNT_ID"
|
||||||
|
```
|
||||||
|
|
||||||
|
Zainstaluj hook:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File ".\install-cloudflare-hook.ps1"
|
||||||
|
```
|
||||||
|
|
||||||
|
Wykonaj pierwszy deploy:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
powershell.exe -NoProfile -ExecutionPolicy Bypass -File ".\deploy-cloudflare.ps1"
|
||||||
|
```
|
||||||
|
|
||||||
|
10. Po wdrożeniu sprawdź:
|
||||||
|
- czy Cloudflare utworzył nowy deployment,
|
||||||
|
- jaki jest adres `*.pages.dev`,
|
||||||
|
- czy aplikacja działa w przeglądarce,
|
||||||
|
- czy aktualne zmiany są widoczne,
|
||||||
|
- czy folder wdrożeniowy zawiera właściwe pliki.
|
||||||
|
|
||||||
|
Historię deploymentów sprawdź poleceniem:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
& "$env:APPDATA\npm\wrangler.cmd" pages deployment list --project-name "NAZWA_PROJEKTU" --json
|
||||||
|
```
|
||||||
|
|
||||||
|
11. Wykonaj test końcowy:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git add .
|
||||||
|
git commit -m "Konfiguracja automatycznego wdrażania Cloudflare"
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
Potwierdź, że przed pushem uruchomił się Wrangler i że Cloudflare utworzył nowy deployment.
|
||||||
|
|
||||||
|
12. Jeśli `git push` nie działa:
|
||||||
|
- sprawdź osobno uwierzytelnienie do repozytorium Git,
|
||||||
|
- nie zakładaj, że problem dotyczy Cloudflare,
|
||||||
|
- jeśli push jest niemożliwy, wykonaj tymczasowy deploy bezpośrednio przez Wrangler,
|
||||||
|
- wyraźnie poinformuj, że lokalny commit może istnieć, ale nie być wysłany do zdalnego repozytorium.
|
||||||
|
|
||||||
|
Pracuj samodzielnie, wykonuj zmiany w plikach, testuj je i nie kończ zadania na samej instrukcji. Nie twórz GitHuba ani GitHub Actions, chyba że użytkownik wyraźnie o to poprosi.
|
||||||
@@ -132,10 +132,6 @@ function render() {
|
|||||||
}
|
}
|
||||||
function setLoaded(rows, source) {
|
function setLoaded(rows, source) {
|
||||||
state.rows = rows;
|
state.rows = rows;
|
||||||
$("#statusDot").classList.add("ready");
|
|
||||||
$("#statusTitle").textContent = "Baza załadowana";
|
|
||||||
$("#statusText").textContent = source;
|
|
||||||
$("#stats").textContent = `${rows.length} rekordów · ${new Set(rows.map((row) => row.model)).size} modeli`;
|
|
||||||
render();
|
render();
|
||||||
renderSuggestions();
|
renderSuggestions();
|
||||||
}
|
}
|
||||||
@@ -145,8 +141,7 @@ async function loadDefault() {
|
|||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||||
setLoaded(parseCsv(await response.text()), "Źródło: atut_baza.csv");
|
setLoaded(parseCsv(await response.text()), "Źródło: atut_baza.csv");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
$("#statusTitle").textContent = "Nie udało się wczytać CSV";
|
$("#results").innerHTML = `<div class="empty">Nie udało się wczytać bazy danych. Uruchom aplikację przez lokalny serwer.</div>`;
|
||||||
$("#statusText").textContent = "Uruchom aplikację przez lokalny serwer, aby wczytać bazę danych.";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
document.querySelectorAll(".tab").forEach((tab) => tab.addEventListener("click", () => {
|
document.querySelectorAll(".tab").forEach((tab) => tab.addEventListener("click", () => {
|
||||||
|
|||||||
+1
-10
@@ -16,15 +16,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<section class="status-card">
|
|
||||||
<div class="status-dot" id="statusDot"></div>
|
|
||||||
<div>
|
|
||||||
<strong id="statusTitle">Wczytywanie bazy…</strong>
|
|
||||||
<span id="statusText">Przygotowuję dane z pliku atut_baza.csv</span>
|
|
||||||
</div>
|
|
||||||
<div class="stats" id="stats"></div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<nav class="tabs" aria-label="Tryb wyszukiwania">
|
<nav class="tabs" aria-label="Tryb wyszukiwania">
|
||||||
<button class="tab active" data-mode="machine">Szukaj maszyny</button>
|
<button class="tab active" data-mode="machine">Szukaj maszyny</button>
|
||||||
<button class="tab" data-mode="filter">Szukaj filtra</button>
|
<button class="tab" data-mode="filter">Szukaj filtra</button>
|
||||||
@@ -38,7 +29,7 @@
|
|||||||
<button id="clearButton" class="clear" type="button" aria-label="Wyczyść wyszukiwanie">×</button>
|
<button id="clearButton" class="clear" type="button" aria-label="Wyczyść wyszukiwanie">×</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="suggestions" class="suggestions" role="listbox" aria-label="Podpowiedzi wyszukiwania"></div>
|
<div id="suggestions" class="suggestions" role="listbox" aria-label="Podpowiedzi wyszukiwania"></div>
|
||||||
<div class="hint" id="searchHint">Wpisz minimum 666 znaki. Wyniki aktualizują się automatycznie.</div>
|
<div class="hint" id="searchHint">Wpisz minimum 3 znaki. Wyniki aktualizują się automatycznie.</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="results-header">
|
<section class="results-header">
|
||||||
|
|||||||
+1
-6
@@ -132,10 +132,6 @@ function render() {
|
|||||||
}
|
}
|
||||||
function setLoaded(rows, source) {
|
function setLoaded(rows, source) {
|
||||||
state.rows = rows;
|
state.rows = rows;
|
||||||
$("#statusDot").classList.add("ready");
|
|
||||||
$("#statusTitle").textContent = "Baza załadowana";
|
|
||||||
$("#statusText").textContent = source;
|
|
||||||
$("#stats").textContent = `${rows.length} rekordów · ${new Set(rows.map((row) => row.model)).size} modeli`;
|
|
||||||
render();
|
render();
|
||||||
renderSuggestions();
|
renderSuggestions();
|
||||||
}
|
}
|
||||||
@@ -145,8 +141,7 @@ async function loadDefault() {
|
|||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||||
setLoaded(parseCsv(await response.text()), "Źródło: atut_baza.csv");
|
setLoaded(parseCsv(await response.text()), "Źródło: atut_baza.csv");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
$("#statusTitle").textContent = "Nie udało się wczytać CSV";
|
$("#results").innerHTML = `<div class="empty">Nie udało się wczytać bazy danych. Uruchom aplikację przez lokalny serwer.</div>`;
|
||||||
$("#statusText").textContent = "Uruchom aplikację przez lokalny serwer, aby wczytać bazę danych.";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
document.querySelectorAll(".tab").forEach((tab) => tab.addEventListener("click", () => {
|
document.querySelectorAll(".tab").forEach((tab) => tab.addEventListener("click", () => {
|
||||||
|
|||||||
+1
-10
@@ -16,15 +16,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<section class="status-card">
|
|
||||||
<div class="status-dot" id="statusDot"></div>
|
|
||||||
<div>
|
|
||||||
<strong id="statusTitle">Wczytywanie bazy…</strong>
|
|
||||||
<span id="statusText">Przygotowuję dane z pliku atut_baza.csv</span>
|
|
||||||
</div>
|
|
||||||
<div class="stats" id="stats"></div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<nav class="tabs" aria-label="Tryb wyszukiwania">
|
<nav class="tabs" aria-label="Tryb wyszukiwania">
|
||||||
<button class="tab active" data-mode="machine">Szukaj maszyny</button>
|
<button class="tab active" data-mode="machine">Szukaj maszyny</button>
|
||||||
<button class="tab" data-mode="filter">Szukaj filtra</button>
|
<button class="tab" data-mode="filter">Szukaj filtra</button>
|
||||||
@@ -38,7 +29,7 @@
|
|||||||
<button id="clearButton" class="clear" type="button" aria-label="Wyczyść wyszukiwanie">×</button>
|
<button id="clearButton" class="clear" type="button" aria-label="Wyczyść wyszukiwanie">×</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="suggestions" class="suggestions" role="listbox" aria-label="Podpowiedzi wyszukiwania"></div>
|
<div id="suggestions" class="suggestions" role="listbox" aria-label="Podpowiedzi wyszukiwania"></div>
|
||||||
<div class="hint" id="searchHint">Wpisz minimum 3 znaki. Wyniki aktualizują się automatycznie.</div>
|
<div class="hint" id="searchHint">Wpisz minimum 2 znaki. Wyniki aktualizują się automatycznie.</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="results-header">
|
<section class="results-header">
|
||||||
|
|||||||
Reference in New Issue
Block a user