# Selfnamed: Cosmetics on demand — Maintainer Guide

This document describes how to publish a new release of the plugin to the official
WordPress.org Plugin Directory via SVN.

The plugin is hosted at:

- **Slug:** `selfnamed-cosmetics-on-demand`
- **SVN repository:** https://plugins.svn.wordpress.org/selfnamed-cosmetics-on-demand/
- **Public page:** https://wordpress.org/plugins/selfnamed-cosmetics-on-demand/

> Day-to-day development happens on GitHub (this repo). WordPress.org SVN is
> only used as the **distribution channel** — we copy the built plugin there
> when we want a new version to roll out to users.

---

## 1. Prerequisites

### 1.1 Tools

- `svn` (Subversion CLI) — on macOS: `brew install svn`
- `zip` (used by `bin/build-zip.sh`)
- `git` working tree clean and on the release commit

### 1.2 WordPress.org credentials

The credentials of the WordPress.org committer account live in 1Password
(Selfnamed vault):

- WordPress.org account / login:
  https://start.1password.com/open/i?a=4WV2UMKUYFFUPJ7WJIXUOTCZQU&v=ffj6menow63xyx2xwcjxtlynq4&i=xvt2vhwgdxd6qdmcdtkrvoniai&h=selfnamed.1password.eu
- SVN commit credentials:
  https://start.1password.com/open/i?a=4WV2UMKUYFFUPJ7WJIXUOTCZQU&v=ffj6menow63xyx2xwcjxtlynq4&i=tauvuan5aqrtbvnim6asajvtku&h=selfnamed.1password.eu

The committer account must be listed under `Contributors:` in `readme.txt` and
must have been added by the plugin owner on WordPress.org. SVN auth uses the
same WordPress.org username/password (no SSH key).

---

## 2. Pre-release checklist

Before publishing, on the release branch / `master`:

1. Bump the version in **both** places — they must match exactly:
   - `selfnamed-cosmetics-on-demand.php` → `Version:` header
   - `readme.txt` → `Stable tag:`
2. Update `Tested up to:` in `readme.txt` if a newer WordPress / WooCommerce
   version was verified.
3. Add a new entry to `changelog.txt` and to the `== Changelog ==` section of
   `readme.txt`.
4. Make sure the working tree is committed and pushed; the release should be
   tagged in git too (`git tag vX.Y.Z && git push --tags`).

---

## 3. SVN layout

WordPress.org uses a fixed SVN layout. After checkout you'll see:

```
selfnamed-cosmetics-on-demand/
├── assets/      # screenshots, banner, icon — NOT shipped to users, only shown on the .org page
├── branches/    # unused for us
├── tags/        # one folder per released version (1.0.0, 2.0.19, ...)
└── trunk/       # the current source of truth — what gets pushed becomes the new release
```

Rules:

- `trunk/` mirrors the latest plugin code.
- A release is created by copying `trunk/` into `tags/<version>/`.
- `assets/` is for the **directory listing** only (banner, icon, screenshots) —
  it is never bundled into the user download.

---

## 4. Publishing a new version

### 4.1 Check out the SVN repo (one-time)

Pick a folder **outside** this git repo, e.g. `~/svn/`:

```bash
mkdir -p ~/svn && cd ~/svn
svn checkout https://plugins.svn.wordpress.org/selfnamed-cosmetics-on-demand/ selfnamed-cosmetics-on-demand-svn
cd selfnamed-cosmetics-on-demand-svn
```

For subsequent releases, just update the existing checkout:

```bash
cd ~/svn/selfnamed-cosmetics-on-demand-svn
svn update
```

### 4.2 Build the release artifact from git

From the git repo root:

```bash
./bin/build-zip.sh
```

This produces `dist/selfnamed-cosmetics-on-demand.zip` containing the plugin
under a top-level `selfnamed-cosmetics-on-demand/` folder, with dev-only files
(`bin/`, `dev/`, `dist/`, `.git*`, `node_modules/`, etc.) excluded. The
contents of that folder are exactly what should land in SVN `trunk/`.

### 4.3 Replace `trunk/` with the new build

From the SVN checkout root:

```bash
# Wipe the current trunk contents but keep the folder itself
rm -rf trunk/*

# Unzip the freshly built plugin into trunk/
unzip -q /path/to/git/repo/dist/selfnamed-cosmetics-on-demand.zip -d /tmp/scod-release
cp -R /tmp/scod-release/selfnamed-cosmetics-on-demand/. trunk/
rm -rf /tmp/scod-release
```

Stage adds and deletes so SVN tracks new/removed files:

```bash
svn status                                  # review what changed
svn add --force trunk
svn status | awk '/^!/ {print $2}' | xargs -r svn delete
```

> `svn add --force` re-adds anything new. The `awk` line removes from SVN any
> file that disappeared from the new build (shown as `!` in `svn status`).

### 4.4 Tag the release

Use SVN's server-side copy — do **not** copy files manually:

```bash
svn copy trunk tags/2.0.19
```

(replace `2.0.19` with the actual version — it must match `Stable tag:` in
`readme.txt` and the `Version:` header in the main PHP file).

### 4.5 Commit

```bash
svn status                                  # final review
svn commit -m "Release 2.0.19"
```

You will be prompted for the WordPress.org username and password (the second
1Password entry linked above). On first use, `svn` will offer to store the
credentials — say yes only if the machine is trusted.

> The new version goes live on https://wordpress.org/plugins/selfnamed-cosmetics-on-demand/
> within a few minutes. Auto-update notifications reach existing installs once
> the WordPress.org cache refreshes (typically under an hour).

---

## 5. Updating the directory page assets (icon / banner / screenshots)

These live in SVN under `assets/` (sibling of `trunk/`), **not** inside
`trunk/`. Naming convention:

- `icon-128x128.png`, `icon-256x256.png`
- `banner-772x250.png`, `banner-1544x500.png` (retina)
- `screenshot-1.png`, `screenshot-2.png`, … (matched by order to the
  `== Screenshots ==` section in `readme.txt`)

To update:

```bash
cp /path/to/new-banner.png assets/banner-772x250.png
svn add --force assets
svn commit -m "Update banner"
```

No tag bump is required — asset commits are independent of plugin releases.

---

## 6. Troubleshooting

- **`svn: E170001: Authentication failed`** — wrong credentials, or the
  WordPress.org account is not a listed committer. Verify with the 1Password
  entry; check the `Contributors:` line in `readme.txt`.
- **New version not showing up on wordpress.org** — `Stable tag:` in
  `readme.txt` (in `trunk/`) must point to a version that exists under
  `tags/`. If it doesn't match, WordPress.org keeps serving the old release.
- **`svn status` shows `?` for new files after build** — they aren't tracked
  yet; run `svn add --force trunk` before commit.
- **Need to fix a botched release** — bump to the next patch version and
  re-publish. Do not rewrite an existing tag; WordPress.org caches them.

---

## 7. Quick reference

```bash
# One-time
svn checkout https://plugins.svn.wordpress.org/selfnamed-cosmetics-on-demand/ ~/svn/selfnamed-cosmetics-on-demand-svn

# Each release
cd ~/svn/selfnamed-cosmetics-on-demand-svn
svn update
./bin/build-zip.sh                          # (run from the git repo)
rm -rf trunk/*
unzip -q <git-repo>/dist/selfnamed-cosmetics-on-demand.zip -d /tmp/scod-release
cp -R /tmp/scod-release/selfnamed-cosmetics-on-demand/. trunk/
rm -rf /tmp/scod-release
svn add --force trunk
svn status | awk '/^!/ {print $2}' | xargs -r svn delete
svn copy trunk tags/<X.Y.Z>
svn commit -m "Release <X.Y.Z>"
```
