今日已更新 184 条资讯 | 累计 37433 条内容
关于我们

标签:#Github

找到 1547 篇相关文章

AI 资讯

A static site that collects form submissions, in one HTML attribute

A static site has no backend. That is the point of one — and it is also why the contact form is the first thing that breaks. The usual answers are a third-party form service with its own signup, a serverless function you now maintain, or a mailto: link nobody clicks. There is a third option that falls out of how static hosting already works: the host is in the path of every HTML response it serves. It can collect the form itself. On harvis.dev that is one attribute: <form harvis-form= "contact" > <input name= "email" type= "email" required > <textarea name= "message" ></textarea> <button> Send </button> </form> Deploy, and submissions show up in the dashboard. No script tag, no API key in the page, no fetch() , no JavaScript at all — the form works with JS disabled, because it is a plain HTML form doing what plain HTML forms have always done. The page I am describing is live at harvis-forms-example.harvis.dev — submit the form and see where you land. Everything below is what makes that page work. What actually happens The rewrite happens on the way out, while the HTML is being served: action and method are replaced with /__harvis/form/contact on your site's own subdomain. Same origin, so there is no CORS, no preflight, and nothing in the page has to know a project id. A honeypot field is inserted. It is positioned off-screen rather than display: none , because a bot that skips hidden inputs is a bot that would otherwise get through. Anything that fills it in gets the success page and is stored nowhere — a bot that can tell it was caught is a bot that tries again differently. data-harvis-redirect="/thanks.html" becomes a hidden field, since the handler never sees your HTML — only what the browser posts. It is re-validated on arrival, and a protocol-relative //somewhere-else is refused. The reply is a 303 , so the browser follows it with a GET and a refresh on the thank-you page cannot post the form twice. The form name is part of a URL and a dashboard heading, so it

2026-08-13 原文 →
AI 资讯

Running the same SQL checks in a browser, CLI and pull request

I wanted one set of SQL checks to work in three places: while exploring a query, from a terminal and during code review. That became SQL Atlas. It is a local, deterministic SQL analyzer with a browser interface, a CLI and a GitHub Action. This article covers the interfaces, the CI contract and the limits of static SQL analysis. One analyzer, three interfaces The analyzer returns structured data instead of printing messages directly. Each interface decides how to present the same result: The browser explains findings and links them to learning material. The CLI returns text, JSON or Markdown and uses stable exit codes. The GitHub Action converts findings into file annotations and a job summary. Keeping presentation outside the analyzer prevents the CLI and Action from becoming separate implementations with different behavior. A CLI needs a contract The CLI accepts one or more files, or SQL through standard input: npx --yes sql-atlas@0.5.1 analyze query.sql echo "SELECT * FROM customers;" | npx --yes sql-atlas@0.5.1 analyze - It supports PostgreSQL, MySQL, Oracle, SQLite, SQL Server and a generic mode. Output can be text for a person, JSON for another program or Markdown for an issue or report. Exit codes are part of the interface: 0 means analysis completed and the configured policy passed. 1 means analysis completed but a severity or score threshold failed. 2 means the command or input was invalid. This distinction matters in CI. A policy failure is not the same as a broken invocation. Turning findings into pull request feedback The Action runs as a bundled Node 24 program and does not download dependencies at runtime. A minimal workflow looks like this: name : SQL review on : pull_request : paths : - " **/*.sql" permissions : contents : read jobs : sql-atlas : runs-on : ubuntu-latest steps : - uses : actions/checkout@v7 - uses : milekv/sql-atlas@v0.5.1 with : paths : | migrations/**/*.sql schema/**/*.sql dialect : postgresql fail-on : critical min-score : 60 Findin

2026-08-13 原文 →
AI 资讯

# 🚀 I Built a Jenkins CI/CD Pipeline From Scratch — Here's Every Bug I Hit (and How I Fixed Them)

A learning-in-public story about Flask, Jenkins, AWS EC2, systemd, and finally shipping a live demo on Vercel. 🎯 TL;DR I built PyPulse, a tiny Flask app, and wired it up to a full CI/CD pipeline: push to GitHub → Jenkins builds → tests → deploys to AWS EC2 → auto-triggered via webhook → managed by systemd. Along the way I broke almost every piece of it at least once, and fixed each one. I also deployed a permanent live demo on Vercel, since my EC2 instance is running on the AWS free trial and won't live forever. 🔗 Live demo: pypulse-pi.vercel.app 🔗 Live demo (health check): pypulse-pi.vercel.app/health If you're learning DevOps and want to see what the real, messy version of "just set up a CI/CD pipeline" looks like — not the polished tutorial version — this is that. 🧰 The Stack Piece Tool Job App Flask + pytest + gunicorn The actual web app and its tests CI/CD Jenkins (on EC2, Ubuntu 22.04) Build → Test → Deploy automation Source control GitHub Single source of truth Trigger GitHub Webhook Auto-runs the pipeline on every push Process management systemd Keeps the app alive on reboot/crash Permanent demo Vercel Live URL that survives EC2 termination 🏗️ The App: PyPulse Nothing fancy on purpose — the whole point of this project was the pipeline, not the app. python app.py from flask import Flask, jsonify from datetime import datetime, timezone app = Flask( name ) @app.route("/") def home(): return jsonify({ "message": "Hello from PyPulse", "time": datetime.now(timezone.utc).isoformat() }) @app.route("/health") def health(): return jsonify({"status": "ok"}), 200 if name == " main ": app.run(host="0.0.0.0", port=5000) Two routes. Two tests. That's it. Small enough that when something broke, I knew it wasn't the app — it was the plumbing around it. That turned out to be the right call, because the plumbing broke a lot. 😅 ⚙️ The Pipeline: Build → Test → Deploy Here's the mental model I ended up with for a Jenkinsfile: Each stage is a gate. If Build fails, Test never runs.

2026-08-13 原文 →