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

标签:#githubactions

找到 27 篇相关文章

AI 资讯

How a Single beforeEach Killed Our CI for 36 Hours

Six failed CI runs. Thirty-six hours of GitHub Actions time. Every run timing out at exactly the 6-hour limit. The culprit was one line in tests/setup.js . The Setup We were building a multi-tenant platform with a PostgreSQL backend — around 76 database models handling everything from user accounts and billing to visitor logs and real-time notifications. The test suite had grown to roughly 1,140 test cases across 36 files. Standard stuff. CI ran on every PR. Tests passed locally. And then one day, CI just... never finished. The Anti-Pattern Here's what the test setup looked like: // tests/setup.js beforeEach ( async () => { const tableNames = await getTableNames (); // 76 tables await sequelize . query ( `TRUNCATE TABLE ${ tableNames . join ( ' , ' )} CASCADE;` ); }); The intent was clean isolation — every test starts with a blank slate. Reasonable in theory. Catastrophic in practice. The Math Do the multiplication: 76 tables × 1,140 tests = 86,640 TRUNCATE operations Each TRUNCATE TABLE ... CASCADE is not a cheap operation. PostgreSQL has to: Acquire exclusive locks on all referenced tables Walk the foreign key graph to find dependent tables Truncate each in dependency order Release locks With a moderately complex schema where most tables reference others (users → societies → members → invoices → payments → ...), a single TRUNCATE ... CASCADE on a central table can fan out into dozens of implicit truncations. Multiply that by 86,640 and you have a test suite that will never complete within any reasonable timeout. Why It Wasn't Caught Sooner Two reasons: 1. It used to be fast. When the suite had 50 tests and 20 tables, this pattern worked fine. 50 × 20 = 1,000 truncations — uncomfortable but survivable. Nobody noticed when the suite crossed a tipping point. 2. Local runs used a different database state. Locally, developers often ran a subset of tests with --grep or file-specific runs. The full suite was only ever run on CI, and CI was slow enough that most assumed i

2026-07-24 原文 →
开发者

Stop Running `terraform apply` From Your Laptop: Building Your First Terraform CI/CD Pipeline with GitHub Actions

One of the biggest mistakes beginners make when learning Terraform is treating their local machine as the deployment server. A typical workflow looks like this: terraform init terraform plan terraform apply While this approach is perfectly fine for learning, it quickly becomes problematic when working on real-world projects with multiple engineers. Consider these questions: Who deployed the infrastructure? Was the infrastructure reviewed before deployment? Can someone else reproduce the deployment? What happens if the engineer's laptop is lost or misconfigured? How do we know exactly what changed? These are some of the reasons Infrastructure as Code (IaC) is almost always integrated with Continuous Integration and Continuous Deployment (CI/CD) pipelines in professional environments. In this article, we'll build a simple Terraform CI/CD pipeline using GitHub Actions. Instead of focusing only on the YAML syntax, we'll first understand why each stage exists and how they work together to produce safe, repeatable infrastructure deployments. What is Terraform CI/CD? Terraform CI/CD is the process of automating the validation, planning, and deployment of infrastructure whenever changes are made to Terraform code. Instead of running Terraform commands manually from a developer's laptop, a CI/CD platform executes those commands automatically in a controlled environment. The workflow typically looks like this: Developer │ ▼ Git Push │ ▼ GitHub Repository │ ▼ GitHub Actions │ ▼ Terraform Init │ ▼ Terraform Validate │ ▼ Terraform Plan │ ▼ Manual Approval │ ▼ Terraform Apply │ ▼ AWS Infrastructure This approach provides consistency, visibility, and security while reducing the chances of human error. Why Not Run Terraform Manually? Running Terraform from your laptop works well for personal projects, but it introduces several risks in a team environment. Manual Deployment CI/CD Deployment Requires someone to remember every command Runs automatically Easy to skip validation Validat

2026-07-23 原文 →
AI 资讯

I Built urldn-link-check — A GitHub Action to Catch Broken Links Before They Reach Production

Documentation is often the last thing developers think about—until a broken link frustrates users or a README sends someone to a 404 page. I wanted a simple way to automatically verify links in Markdown documentation during CI, so I built urldn-link-check. It's an open-source GitHub Action and CLI that scans your documentation and reports issues before they're merged. Features ✅ Detect broken links (404/500) ↪️ Detect redirect chains 🔒 Detect insecure HTTP links 📏 Find overly long URLs 📄 Scan Markdown & MDX files ⚡ Fast concurrent scanning 💬 GitHub PR summaries 📊 JSON & Markdown reports Installation npm install -D urldn-link-check or npx urldn-link-check . GitHub Action uses: urldn/link-check@v1 That's it. Every push or pull request can automatically verify your documentation. Why I Built It While maintaining documentation, I noticed that broken links often go unnoticed until someone reports them. Instead of checking them manually, I wanted a lightweight tool that integrates directly into GitHub Actions and fits naturally into a CI workflow. Open Source The project is MIT licensed and contributions are welcome. ⭐ GitHub: https://github.com/urldn/link-check 📦 npm: https://www.npmjs.com/package/urldn-link-check https://www.npmjs.com/package/urldn-link-check This is the first developer tool in the URLDN ecosystem, with more open-source projects planned in the future. If you have ideas or feedback, I'd love to hear them.

2026-07-23 原文 →
AI 资讯

Commit Cron: A Simple Daily Commit Bot with GitHub Actions

I built Commit Cron , a small GitHub Actions experiment that creates one automated commit every day. The project updates a text file with the latest execution time, commits the change using the github-actions[bot] account, and pushes it back to the repository. View the project on GitHub: Commit Cron How It Works The workflow runs every day at 10:00 AM Asia/Manila time. on : schedule : - cron : " 0 10 * * *" timezone : " Asia/Manila" workflow_dispatch : The workflow_dispatch trigger also lets me run the workflow manually from the GitHub Actions tab. The workflow checks out the repository, creates the bot directory when needed, and updates bot/last-run.txt : mkdir -p bot printf "Last automatic update: %s \n " \ " $( TZ = Asia/Manila date '+%Y-%m-%d %H:%M:%S %:z (Asia/Manila)' ) " \ > bot/last-run.txt The file contains a timestamp similar to: Last automatic update: 2026-07-17 10:03:24 +08:00 (Asia/Manila) After updating the file, the workflow configures the GitHub Actions bot identity and creates the commit: git config user.name "github-actions[bot]" git config user.email \ "41898282+github-actions[bot]@users.noreply.github.com" git add bot/last-run.txt git commit -m "chore: daily automated update" Before pushing, it pulls the latest branch changes with rebase: git pull --rebase origin " ${ GITHUB_REF_NAME } " git push origin "HEAD: ${ GITHUB_REF_NAME } " This helps prevent the push from failing when another commit is added while the workflow is running. Repository Structure . ├── .github/ │ └── workflows/ │ └── daily-commit.yml ├── bot/ │ └── last-run.txt ├── LICENSE └── README.md Why I Built It Commit Cron is a small demonstration of: Scheduled GitHub Actions workflows Manual workflow triggers Automated file updates Bot-generated Git commits Repository write permissions using GITHUB_TOKEN The workflow uses: permissions : contents : write This allows the built-in GitHub token to push the generated commit. Important Note The automated commits only confirm that the work

2026-07-17 原文 →
开发者

Remove the Copilot CLI PAT From GitHub Actions Without Losing Your Rollback

GitHub announced on July 2, 2026 that Copilot CLI no longer needs a personal access token when it runs in GitHub Actions. Primary source: GitHub Changelog, July 2, 2026 . Deleting a secret is easy. Proving the workflow still works—and recovering without hurriedly pasting credentials back into YAML—is the useful part. This is an unexecuted migration template, not a report from a production repository. Make one reversible change First find every place the old secret enters the job, including reusable workflows: git grep -nE 'COPILOT_PAT|COPILOT_GITHUB_TOKEN|GH_TOKEN|github_pat' Record the workflow, job, pinned CLI version, permissions block, and previous known-good commit. Never print environment variables while debugging. Then remove only the PAT injection. Do not upgrade the runner and CLI in the same patch. jobs: copilot-check: permissions: contents: read - env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_PAT }} steps: - uses: actions/checkout@<PINNED_COMMIT> - run: ./scripts/setup-copilot-cli.sh - run: ./scripts/run-bounded-check.sh The scripts are placeholders for repository-owned commands. “No PAT required” does not mean “no identity or permissions exist”; follow the current setup documentation and keep permissions explicit. Add a canary with two proofs The canary should show that the legacy token is absent and that the existing bounded task still satisfies its output contract. name : copilot-cli-auth-canary on : workflow_dispatch permissions : contents : read jobs : canary : runs-on : ubuntu-latest timeout-minutes : 10 steps : - uses : actions/checkout@<PINNED_COMMIT> - name : Verify legacy PAT is absent run : | test -z "${COPILOT_PAT:-}" test -z "${COPILOT_GITHUB_TOKEN:-}" - run : ./scripts/setup-copilot-cli.sh - run : copilot --version - run : ./scripts/run-bounded-check.sh Use a read-only, cheap task. “Fix whatever you find” is not a canary; it is a small deployment wearing a fake mustache. Define pass criteria before clicking Run: absent legacy variables, e

2026-07-16 原文 →
AI 资讯

We Made Our AI-vs-Human PR Stats a Public Live Dashboard

A while back I wrote about 64% of our merged PRs being written by AI . A few people (reasonably) asked: "nice story, but can I verify any of that?" So we put it on a public, auto-updating dashboard: 👉 www.codens.ai/stats/en It shows, for our GitHub organization: What % of merged PRs are authored by AI agents (currently 65%) Median time from PR-open to merge (2 minutes) Who merged what — task-execution agents vs maintenance bots vs auto-fix vs humans Weekly AI-merge counts and a per-repository breakdown Every number is tallied straight from the GitHub API by a small collector script, and the page regenerates itself weekly. We can't inflate it — it's measured, and the down weeks show up too (that's kind of the point). Why bother making it public Two reasons. 1. "Trust me bro" doesn't scale. When you claim most of your code is AI-written, the only honest move is to expose the raw counts so anyone can sanity-check them. The dashboard is that receipt. 2. It's a live dogfooding test. The whole thing — the PRD, the implementation, the review, the auto-fix on production errors — runs on Codens , our own AI dev-automation suite. If our own numbers ever tanked, the dashboard would be the first place it'd show. Public accountability is a good forcing function. Funny footnote: the dashboard itself was code-reviewed by our own AI reviewer before it shipped, and it caught two real bugs — an OG-image percentage that had drifted out of sync with the live number, and a broken error-fallback that would have blanked the page on malformed data. The tool built to sell "AI reviews your PRs" reviewed the PR that announces it. We'll take it. If you want to see the same machinery on your repos, there's a 14-day free trial (no card): codens.ai . Japanese version of the dashboard is here .

2026-07-07 原文 →
AI 资讯

Securing Your Terraform Infrastructure with Checkov and GitHub Actions

Infrastructure as Code (IaC) has revolutionized how we provision and manage cloud resources. Tools like Terraform, Pulumi, and OpenTofu allow us to define infrastructure using code, making it versionable, repeatable, and scalable. However, with great power comes great responsibility. Misconfigurations in IaC can lead to massive security breaches, such as publicly exposed data storage or overly permissive access roles. This is where Static Application Security Testing (SAST) comes in. SAST tools analyze your source code to find security vulnerabilities before the code is deployed. In this article, we'll explore how to apply SAST to a Terraform project using Checkov , a popular open-source static analysis tool for IaC, and how to automate this process using GitHub Actions. (Note: We are intentionally avoiding tfsec for this demonstration to explore other powerful alternatives). Why Checkov? Checkov, created by Bridgecrew (now part of Prisma Cloud), is a static code analysis tool for IaC. It scans cloud infrastructure provisioned using Terraform, Terraform plan, Cloudformation, Kubernetes, Dockerfile, Serverless, or ARM Templates and detects security and compliance misconfigurations. It includes hundreds of built-in policies covering security and compliance best practices for AWS, Azure, and Google Cloud. The Demo Scenario: A Vulnerable S3 Bucket Let's start by creating a simple Terraform configuration for an AWS S3 bucket. We will intentionally introduce a security misconfiguration: making the bucket public without encryption. Create a file named main.tf : # main.tf provider "aws" { region = "us-east-1" } resource "aws_s3_bucket" "my_vulnerable_bucket" { bucket = "my-company-public-data-bucket-12345" } # Misconfiguration 1: Public Read Access resource "aws_s3_bucket_acl" "example" { bucket = aws_s3_bucket . my_vulnerable_bucket . id acl = "public-read" } If we were to deploy this, anyone on the internet could read the contents of this bucket. Let's see how Checkov can

2026-07-05 原文 →
AI 资讯

Copilot CLI drops the PAT requirement inside GitHub Actions

GitHub said this week that Copilot CLI, when it runs inside a GitHub Actions workflow, will accept the built-in GITHUB_TOKEN for authentication. Per the July 2 changelog, the previous path required creating and storing a personal access token. The operational read is small and precise: one fewer human-owned credential to mint, rotate and inherit. The exact scope of the change The changelog covers a narrow surface. It applies to Copilot CLI when invoked from a GitHub Actions workflow, and it swaps the required credential from a PAT to the workflow's ambient GITHUB_TOKEN . GitHub does not describe changes to how Copilot CLI authenticates outside Actions, and this post will not extrapolate to those contexts. If your Copilot CLI usage lives on a developer laptop or in another CI system, nothing in this announcement moves for you. Why the PAT was the wrong credential to leave in the loop A personal access token has almost none of the properties you would want from an automation credential. It does not expire on a job boundary. It carries a person's identity, not the workflow's. It sits in Actions secrets long enough to outlive the engineer who created it. And its scopes were chosen by that engineer, at that moment, often wider than the job actually needs. GITHUB_TOKEN is the opposite shape. Actions mints it at the start of a job, scopes it through the workflow's permissions: block, and revokes it when the job ends. If the token leaks, the window for abuse is the runtime of the job, not the years until somebody remembers to rotate it. When the person who wrote the workflow leaves, the pipeline does not silently break because a token expired with their account. For scripted Copilot CLI calls that had to be wrapped in a PAT, that is the whole win. The tool authenticates against the workflow instead of against a human. Wiring it up The workflow-side pattern is the same one every GITHUB_TOKEN -consuming step already follows: declare permissions: explicitly at the job level, k

2026-07-04 原文 →
AI 资讯

glasp v0.3.0 & v0.4.0 — PKCE Support, Timeouts, and Retries

Last time I wrote about using glasp, a Go-based, npm-free CLI for Google Apps Script (GAS), in GitHub Actions. Previous post: Lean, Fast, Simple — npm-free GAS Deployment on GitHub Actions with glasp This time, a quick rundown of what landed in v0.3.0 and v0.4.0 . v0.3.0: PKCE support glasp login now supports PKCE (RFC 7636) as an opt-in. glasp login --pkce # or GLASP_USE_PKCE = 1 glasp login Each login generates a code_verifier and sends an S256 code_challenge to Google. It's a defense against authorization code interception, and it coexists fine with the existing client_secret flow. It only applies to the interactive login — --auth / GLASP_AUTH for CI is untouched. Off by default. Worth turning on if you're in a stricter security environment. v0.4.0: Timeouts and retries The focus here is basically "can this run unattended in CI/CD without falling over." Timeouts Script API requests previously had no timeout — a stuck request could hang the job indefinitely. v0.4.0 adds a 180s default. glasp push --timeout 60 # set to 60s glasp push --no-timeout # disable Also configurable via GLASP_TIMEOUT / GLASP_NO_TIMEOUT env vars or timeoutSeconds in .glasp/config.json . Priority: --no-timeout > flag/env > config > default. If the config file is broken, it warns instead of silently falling back. Retries Transient failures (5xx, 429) now get retried automatically. glasp push --max-retries 5 glasp push --no-retries 3 retries by default (up to 4 attempts total) Only applies to idempotent commands: push , pull , clone , list-deployments Commands with side effects ( create-script , run-function , etc.) are never retried Exponential backoff with jitter, respecting Retry-After It's implemented as a single http.RoundTripper wrapper, so the Google SDK itself isn't touched — same pattern as the timeout implementation. retryTransport → oauth2.Transport → http.DefaultTransport Some refactoring, too Internal packages got reorganized ( #107 ), and the hand-rolled retry transport was swappe

2026-07-02 原文 →
AI 资讯

The GitHub Actions workflow that's been failing for weeks (and how to find yours)

trpc has a scheduled workflow called "Lock Issues & PRs." Its own scorecard shows it failing on almost every run. It is still scheduled, still running, still red. trpc ships excellent software, which is exactly the point: if a project this careful has a workflow that has been red for ages, the rest of us almost certainly do too. It is not a one-off. drizzle-orm has one ("Unpublish release"). cal.com has one ("PR Update"). I scanned 35 popular open-source repos and the same thing kept turning up: a scheduled workflow that fails on nearly every run, quietly, for a long time. Why nobody notices GitHub does email you when a scheduled workflow fails. So how do these survive? Two reasons. First, those emails are routine. You get them for flaky reruns and transient blips too, so you filter them out. Second, a workflow that is always red stops reading as a signal. It is just how that row looks now. I did exactly this on my own project. GitHub emailed me that a workflow had failed. The next day it emailed again. I saw it, told myself I would fix it tomorrow, and promptly forgot. It was my nightly database backup, quietly broken the whole time, and I only caught it when a failure-rate number crept up where I would notice. An always-red workflow is not free It burns minutes every run to produce nothing but a red X. Worse, it trains you to ignore the failure that actually matters: the day a real one lands in the same inbox you have learned to skim past. How to find yours Open your Actions tab and look at the scheduled workflows, the cron-triggered ones nobody watches. If the last several runs are all red, you found one. From the CLI: gh run list --workflow = "Lock Issues & PRs" --status = failure What to do about it Two honest options: fix it, or if the workflow is genuinely abandoned, turn it off. Do not leave it scheduled and red. gh workflow disable "Lock Issues & PRs" Or drop the schedule trigger from the workflow file if it should not run on a timer at all. A disabled work

2026-06-30 原文 →
AI 资讯

Why your GitHub Actions CI is slow (and how to speed it up)

Two days ago GitHub emailed me to say one of my workflows had failed. The next day it emailed me again. I saw it, told myself I would fix it tomorrow, and promptly forgot. It was my nightly database backup, quietly broken the whole time, and I only caught it because a failure-rate number nudged up. A failed run at least gets you an email. A slow run gets you nothing. GitHub never pings you when CI quietly takes twice as long, runs the whole suite twice per PR, or rebuilds dependencies from scratch every time. That waste compounds where no one looks. Here are the usual culprits, each with the exact fix. When I scanned 35 popular open-source repos, not one had a fully clean config. 32 of 35 had no concurrency control, 33 of 35 had no job timeouts, and 22 of 35 ran the full suite twice on every PR. If projects this polished leave minutes on the table, the rest of us definitely do. Your suite runs twice on every PR Trigger a workflow on both push and pull_request and, for a branch in the same repo, opening a PR fires both. You just paid for two identical runs. This one is pure waste and it can roughly halve your PR-related minutes. Trigger on pull_request , and keep push for your default branch: on : push : branches : [ main ] pull_request : Old runs don't cancel when you push again Push a fix 30 seconds after the first push and, with no concurrency group, both runs go to completion. The first is dead weight, and it is holding a slot in your queue while it finishes. This hides even when you do have a group: astro has a concurrency group on one workflow but left off cancel-in-progress , which our scan estimates leaves roughly 1,850 minutes a month on the table. Add a group keyed on the branch, with cancel-in-progress , so a new push supersedes the old run: concurrency : group : ${{ github.workflow }}-${{ github.ref }} cancel-in-progress : true Every run reinstalls dependencies from scratch No cache means every run re-downloads and rebuilds your dependencies. On a typical

2026-06-30 原文 →
AI 资讯

A homemade CI/CD pipeline with GitHub Actions

In the previous article on hosting a Next.js app on a VPS , I'd left the deployment pipeline as a rough sketch: four lines to say "it ships to production on its own when you push." That's the piece I want to open up here, because it's what separates a VPS you fuss over by hand from infrastructure you can forget about. There's a stubborn myth that CI/CD is a big-company thing, with a dedicated DevOps team and six-figure tooling. Not true. The pipeline that deploys this portfolio fits in two YAML files, you can read it in five minutes, and it gives me back exactly the comfort I liked about Vercel: I push to master , I go grab a coffee, the app is live when I'm back. The one thing I gained along the way is knowing precisely what happens between the git push and the running container. Four steps, in this order Deployment is a chain. On every push to master , GitHub Actions runs lint, security scan, image build, and deploy. What matters is the needs : as long as a step fails, the following ones don't start. A critical vulnerability caught by the scan, and the image never gets built. At all. jobs : lint : # ESLint runs-on : ubuntu-latest # ... security : # Trivy scan (reusable workflow) uses : ./.github/workflows/security.yml build-push : # build the Docker image → push to GHCR needs : [ lint , security ] # ... deploy : # SSH to the VPS → docker compose pull && up -d needs : [ build-push ] # ... Lint first, because it's the cheapest step and there's no point building an image if ESLint is already screaming. The scan next, as a barrier. Then the build, which produces the Docker image and pushes it to GHCR, GitHub's container registry (private, in my case). And finally the deploy, which connects over SSH to the VPS, pulls the new image and restarts the container. Four links, each blocking the next. That's the whole secret. The security scan is in the path, not in a review "for later" This is the one I won't budge on. Dependency security, in a lot of projects, is a Dependabo

2026-06-28 原文 →
AI 资讯

GitHub Actions adds a background marker, and the linear job stops being the only shape

A small word that changes the rhythm of a job For as long as I have been writing Actions workflows I have been carrying a quiet workaround in my head. Want to warm a cache while the build runs? Append & to the shell command, then squint at logs that arrive out of order and pray the job doesn't exit on you. It worked, sort of. It also meant that anything more interesting than "run one thing, then the next thing" lived as folklore, hidden inside run: blocks. GitHub closed that gap this week. On June 25 the Actions changelog announced that steps inside a job can now run concurrently, marked with a new background keyword and supported by helpers to wait for them and cancel them. Until now, the changelog notes, every step in a workflow ran in sequence, with each step starting only after the previous one completed. That single rule has shaped every workflow I have ever written. It is gone, and the replacement is the kind of feature you don't notice until the day you reach for it and it's there. What the keywords actually do There are four pieces, all of them documented in the announcement. background: true is the entry point. Set it on a step and that step starts running, and the next step starts immediately. It does not block the job. wait and wait-all are the rendezvous. wait pins on one or more named background steps and pauses until they finish. wait-all is the same idea against every background step still in flight. Either way you get back into a linear flow on your terms. cancel is the cleanup. It gracefully terminates a background step when you no longer need it, which is the missing piece if you have ever tried to kill a long-running side process from inside a job and ended up shelling out to kill . parallel is the convenience wrapper. The changelog describes it as taking a group of steps and converting them into background steps with a wait placed after. For the common "fan out, then join" shape, you write one block instead of decorating five steps by hand. Where

2026-06-26 原文 →
AI 资讯

Three post-deploy checks I run after every Cloudflare Pages build

After spending two weeks debugging issues that only showed up in production — a sitemap _redirects rule that was blocking my own sitemap-index.xml and a Bluesky image upload race against Cloudflare Pages deploy lag — I added three post-deploy checks to my workflow. They're fast and specific to the failure modes I've actually hit, not a full end-to-end test suite. Three sites (aiappdex.com, findindiegame.com, ossfind.com) on Cloudflare Pages with Astro 5 SSG. Here's what I check. Check 1: Sitemap reachability The simplest check and the one I should have had from day one. After a Cloudflare Pages deploy, I verify that sitemap-index.xml is reachable and returning 200 on all three domains: for domain in aiappdex.com findindiegame.com ossfind.com ; do status = $( curl -s -o /dev/null -w "%{http_code}" "https:// $domain /sitemap-index.xml" ) echo " $domain /sitemap-index.xml → $status " if [ " $status " != "200" ] ; then echo "FAIL: $domain sitemap unreachable" fi done I also check sitemap-0.xml — the actual URL sub-sitemap that @astrojs/sitemap generates — and assert that it contains at least a minimum expected URL count. For aiappdex.com that threshold is 1,000; if it drops below that after a deploy, the ETL data pipeline probably broke silently. The reason this check exists: I had a _redirects rule rewriting sitemap-index.xml → sitemap-0.xml as an emergency workaround that turned out to be wrong. It was live for five days before I found it. The rule was blocking the real sitemap-index.xml from reaching crawlers while appearing fine in the browser (which followed the redirect). Curl with -o /dev/null -w "%{http_code}" doesn't follow redirects by default, so it would have caught this immediately. Check 2: IndexNow batch submission After every successful sitemap check, I run node scripts/indexnow.mjs . The script reads the live sitemap XML from each domain, collects all URLs, and POSTs them to the IndexNow endpoint for Bing, Yandex, Naver, and Seznam using site-specific k

2026-06-21 原文 →
AI 资讯

Three post-deploy checks I run after every Cloudflare Pages build

After spending two weeks debugging issues that only showed up in production — a sitemap _redirects rule that was blocking my own sitemap-index.xml and a Bluesky image upload race against Cloudflare Pages deploy lag — I added three post-deploy checks to my workflow. They're fast and specific to the failure modes I've actually hit, not a full end-to-end test suite. Three sites (aiappdex.com, findindiegame.com, ossfind.com) on Cloudflare Pages with Astro 5 SSG. Here's what I check. Check 1: Sitemap reachability The simplest check and the one I should have had from day one. After a Cloudflare Pages deploy, I verify that sitemap-index.xml is reachable and returning 200 on all three domains: for domain in aiappdex.com findindiegame.com ossfind.com ; do status = $( curl -s -o /dev/null -w "%{http_code}" "https:// $domain /sitemap-index.xml" ) echo " $domain /sitemap-index.xml → $status " if [ " $status " != "200" ] ; then echo "FAIL: $domain sitemap unreachable" fi done I also check sitemap-0.xml — the actual URL sub-sitemap that @astrojs/sitemap generates — and assert that it contains at least a minimum expected URL count. For aiappdex.com that threshold is 1,000; if it drops below that after a deploy, the ETL data pipeline probably broke silently. The reason this check exists: I had a _redirects rule rewriting sitemap-index.xml → sitemap-0.xml as an emergency workaround that turned out to be wrong. It was live for five days before I found it. The rule was blocking the real sitemap-index.xml from reaching crawlers while appearing fine in the browser (which followed the redirect). Curl with -o /dev/null -w "%{http_code}" doesn't follow redirects by default, so it would have caught this immediately. Check 2: IndexNow batch submission After every successful sitemap check, I run node scripts/indexnow.mjs . The script reads the live sitemap XML from each domain, collects all URLs, and POSTs them to the IndexNow endpoint for Bing, Yandex, Naver, and Seznam using site-specific k

2026-06-21 原文 →
AI 资讯

Comment orchestrer un double déploiement automatique sur Vercel & GitHub Pages avec GitHub Actions

Introduction Dans le cadre de mon apprentissage des pratiques DevOps modernes, j’ai conçu et implémenté un pipeline CI/CD (Continuous Integration / Continuous Deployment) capable de déployer automatiquement une application web frontend sur deux environnements de production distincts : Vercel et GitHub Pages . Cette mission constitue une application concrète des concepts fondamentaux du DevOps, notamment l’automatisation des processus, la réduction des interventions manuelles et la mise en place d’une chaîne de livraison logicielle fiable et reproductible. Tableau comparatif des plateformes Dans ce projet, le déploiement sur les deux plateformes n’est pas un doublon mais une démarche pédagogique et technique délibérée permettant de tester la flexibilité de l'orchestrateur. Voici comment elles se comparent : Critère GitHub Pages Vercel Hébergement Statique uniquement Statique + SSR + Serverless Domaine gratuit username.github.io projet.vercel.app CI/CD intégré Via GitHub Actions Natif + GitHub Actions Performance Bonne Excellente (Edge Network) Previews PR Non Oui (automatique) Gratuit Oui (illimité) Oui (avec limites) Cas d’usage Portfolios, docs Apps React/Next.js, SaaS ⚠️ Le problème du double déploiement : Laisser Vercel en mode automatique génère un conflit critique avec GitHub Actions. Pour éviter que deux builds s'exécutent en parallèle, j'ai désactivé le déploiement natif de Vercel en ajoutant un fichier vercel.json à la racine contenant "git": { "deploymentEnabled": false } . Le pipeline complet — deploy.yml Voici le code source du fichier de configuration de l'orchestrateur GitHub Actions ( .github/workflows/deploy.yml ). Ce script gère séquentiellement l'installation, le build et la publication vers nos deux cibles : name : CI/CD -- Deploy to Vercel & GitHub Pages # Declenchement : uniquement sur push vers main on : push : branches : - main jobs : build-and-deploy : runs-on : ubuntu-latest permissions : contents : write steps : # Etape 1 : Recuperer le code

2026-06-17 原文 →
AI 资讯

Building a Kaggle Competition Notification Bot

I built a tool called "kaggle-dingdong" that automatically fetches Kaggle competition information and sends notifications to Email, Slack, and Discord. It runs daily on a schedule via GitHub Actions, and you get notified whenever a new competition is published. https://github.com/asherish/kaggle-dingdong Why I Built This Checking the Kaggle competitions page every day is tedious. Featured competitions in particular have entry deadlines, so missing them means losing the opportunity. While RSS feeds and official notification features exist, I wanted notifications delivered directly to the channels I actually use (Discord and Slack), so I built my own. Tech Stack Python 3.13 uv — Package manager and build tool (by Astral) Kaggle Python SDK v2.0.0 — Fetching competition info GitHub Actions — Automated daily execution at 09:00 UTC pytest — Testing Three notification channels are supported: Channel Method Format Email SMTP HTML (card layout) Slack Incoming Webhook Block Kit Discord Webhook Rich Embed Architecture GitHub Actions (cron: daily at 09:00 UTC) ↓ Fetch competition list via Kaggle API ↓ Filter by conditions in config.json ↓ Compare with sent history to extract unnotified competitions ↓ Send notifications to configured channels ↓ Update sent history (max 200 entries) The project structure is as follows: kaggle-dingdong/ ├── src/kaggle_dingdong/ │ ├── __main__.py # Entry point │ ├── config.py # Configuration loading │ ├── competitions.py # Fetch & filter competitions from Kaggle API │ ├── email_sender.py # Email notifications │ ├── slack_sender.py # Slack notifications │ ├── discord_sender.py # Discord notifications │ └── history.py # Sent history management ├── tests/ # pytest tests ├── config.json # Filter configuration └── .github/workflows/ └── notify.yml # GitHub Actions workflow Implementation Highlights Fetching and Filtering Competitions The Kaggle SDK is used to fetch the competition list. In addition to the default sort order, it also fetches with recentl

2026-06-17 原文 →
AI 资讯

Tag release pipelines without a 400-line GitHub Actions workflow

You push v1.2.3 and expect a predictable sequence: tests pass → version is resolved → GitHub Release is created . In practice, teams usually pick one of two painful options: One giant workflow — every stage in a single YAML file. It works until you need reuse, workflow_call , or different triggers per stage. workflow_run chains — workflow A triggers workflow B. Passing outputs between runs is awkward, and renaming a workflow breaks the chain silently. There is a middle path: keep small, focused stage workflows (the ones you already have), declare order and wiring in one pipeline file , and use a single orchestrator step on tag push. This tutorial uses pipeline-compose-run — available on the GitHub Marketplace — and a copy-paste example you can drop into any repo. Full example (copy .github/ ): examples/run-tag-release What we are building On git push origin v* : release.yml ← one job, one action step └─ pipeline.yml ← declares order + wiring ├─ ci.yml ├─ stage-version-sync.yml → exports version └─ stage-release-publish.yml ← receives version No generated workflow to commit. No manual workflow_run graph. Step 1 — Entry workflow Create .github/workflows/release.yml : name : Release on : push : tags : [ " v*" ] permissions : contents : write actions : write jobs : run-pipeline : runs-on : ubuntu-latest steps : - uses : actions/checkout@v6 - uses : aeswibon/pipeline-compose-run@v0.3.0 with : pipeline_file : .github/pipelines/pipeline.yml github_token : ${{ github.token }} The actions: write permission is required because the action dispatches your stage workflows via workflow_dispatch . Step 2 — Pipeline file (order only) Create .github/pipelines/pipeline.yml : name : pipeline version : 1 stages : - id : ci workflow : .github/workflows/ci.yml - id : version-sync workflow : .github/workflows/stage-version-sync.yml needs : - ci outputs : - version - id : release-publish workflow : .github/workflows/stage-release-publish.yml needs : - version-sync inputs : version : ${{ co

2026-06-14 原文 →