HTML6 GamesFree Web Games / devlog

No install. Just play.

Free mini games right in your browser. Sign in to save your records to your account and pick up on any device.

All games
All games
All dev log posts

Three tries in one day to decide what not to deploy

Oct 25, 2026 Β· Tools Β· ν•œκ΅­μ–΄

This site has no build step. The source files are the site, and the whole repository root goes to Firebase Hosting. That means any file in the repository can end up on the site. Tools, documents, art sources and private settings must not. I changed how I decide what to leave out three times in a single day.

Firebase Hosting is Google's static site hosting. Files listed in the ignore list of the firebase.json config file are not uploaded. A deploy is done by GitHub Actions, which checks the repository out fresh, so files that git ignores don't exist in the deploy environment at all. The question was how to pick out the files that are in git but must not go up.

At first I filtered by extensions such as *.md and by auth file names (gha-creds-*). I kept the game status in a list.json inside the games folder, which is a folder published on the site. I excluded just that file by name, but there was no way to check whether anything had slipped through. If a file isn't caught by a rule you can't know, and one mismatch quietly puts a file online. A file I meant to keep private did get served from the site once.

I moved the status file to a config/ folder and excluded config/** as a whole. A comment inside a deployed file still mentioned the file's path, so I removed that too. I added two checks to the deploy step. It fails if config/** is missing from the ignore list. It also fails if a deployed file mentions the status file's name. Moving to folders made sure this one file was blocked. But the other files I had been filtering with name rules like *.md were still the same.

The same day I unified the rule. What stays off the site is decided only by the names of folders directly under the root and names that start with a dot. Tools go in tools/, documents in docs/, operational settings in config/, art sources in art-src/ and logs in logs/. I removed every extension and filename rule.

"ignore": ["config/**", "tools/**", "docs/**", "logs/**", "art-src/**",
           "**/.*", "**/.*/**", "firebase.json", "CLAUDE.md", "games/CLAUDE.md"]

For that I had to move every file that depended on a name rule into an excluded folder. The documents (CREDITS, NOTES, TODO) went to docs/, the security rules file to config/, the new game template to tools/game-template/, and each game's art source to art-src/. The auth file is created during the deploy, so instead of excluding it by name I made the workflow move it out of the working folder.

Stop the deploy on anything unknown

The check matters more. In the step that builds the deploy copy, every entry in the root is examined. Each one must be an excluded folder, a name starting with a dot, a file listed in the ignore list, or in the list of site files. If an entry is in none of those, the deploy fails.

const unknown = fs.readdirSync(ROOT).filter((f) => !f.startsWith('.')
  && !outDirs.includes(f) && !ignore.includes(f) && !SITE_ROOT.includes(f));
if (unknown.length) throw new Error(`unknown root entries: ${unknown.join(', ')}`);

This is a simplified example. The point is that it is an allow list. When you create a new file in the root, a person has to decide whether it goes on the site before the deploy will pass. The devlog/ folder I created for this dev log also had to be added to the list of site files by hand.

References

More posts

Add to Home Screen

  1. Tap the Share button at the bottom of the screen (top on iPad). It looks like a square with an arrow pointing up.
  2. Scroll down and tap "Add to Home Screen".
  3. Tap "Add" at the top right. The HTML6 Games icon appears on your home screen.

This works in Safari. Opened from the home screen, it runs without the address bar, like an app, and even offline.