Generate then edit
Collect the commits since the last tag, then rewrite them as consumer facing lines. The generated list is the safety net that nothing was forgotten; the edit is what makes it readable.
Keep the file in the repo
The changelog ships with the code, so the release that added a feature and the line describing it are one diff apart. A changelog only on a website drifts, and drift is what makes it a lie.