WordPress-lisäosan kehitysprosessi

Kehitän ja ylläpidän WordPressin Relevanssi-hakulisäosaa ja sen kaupallista versiota Relevanssi Premiumia. Lisäosien kehityksen hallinnointi on sen verran monipuolinen prosessi, että ajattelin kiinnostavaksi vähän avata toimintatapojani.

Relevanssi WordPress.orgin plugin-hakemistossa.

Jaettua koodia

Kun ylläpidetään kahta samankaltaista, mutta erilaista tuotetta, koodin on oltava mahdollisimman pitkälle samaa. Tämän asian opin melko pian. Eri versioiden ylläpitäminen oli työlästä, kun eri versioissa oli eri tiedostot ja toiseen tehtyjen muutosten siirtäminen toiseen oli tarkkuutta vaativaa käsityötä.

Nyt runko on sellainen, että ilmaisessa ja Premiumissa on molemmissa yhteinen runko, sama lib-hakemisto löytyy molemmista ja on kummassakin tismalleen sama. Jos näihin perustoimintoihin tarvitsee Premiumissa lisätä uutta toiminnallisuutta, se toiminnallisuus määritellään tuon hakemiston ulkopuolella olevissa tiedostoissa ja sen olemassaolo tarkistetaan function_exists()-kutsuilla.

Näin Premiumin puolella tehdyt muutokset synkronoituvat ilmaisversioon hyvin nopeasti, kopioimalla lib-hakemiston sisältö sellaisenaan. Ilmaisversiossa tämän hakemiston ulkopuolella ei ole juuri mitään, mikä vaatisi muutoksia.

Relevanssi Premiumin hakemistorakennetta.

Versionhallinta

Versionhallinta on tietysti pakollinen juttu. Ilmaisversion on pakko olla WordPress.orgin SVN-repossa, mutta sitä ei kyllä kannata käyttää yhtään enempää kuin on pakko, eikä näin ole tarkoituskaan.

SVN and the Plugin Directory are a release repository. Unlike Git, you shouldn’t commit every small change, as doing so can degrade performance. Please only push finished changes to your SVN repository.

Pääasiallisena versionhallintana on toiminut Premiumin yksityinen repo, joka oli alunperin Bitbucketissa ja nykyään GitLabissa. Ilmaisversio oli pitkään vähän sivuroolissa eikä erikseen versionhallinnassa, mutta sitten ryhdistäydyin ja laitoin ilmaisversion GitHubiin ja teen sinne yhtä tarkat ja pienet commitit kuin yksityiseen repooni.

Vaatii hieman lisävaivaa tehdä commitit kahteen kertaan, mutta näen prosessin vaivan arvoiseksi. Koodin oleminen GitHubissa tekee sen tarkastelemisesta helpompaa muille, pienit ja tarkat commitit ovat niin ikään hyvä ja muidenkin elämää helpottava asia. Olen saanut GitHubiin pari pull requestia ja olen myös käyttänyt GitHubia paljon kehitysversioiden jakamiseen tukifoorumilla – ”tämä korjaus on tulossa seuraavaan versioon, jos haluat testata jo nyt hae päivitetty tiedosto täältä”.

Näkymä Relevanssi Premiumin versionhallintaan.

Kehitysprosessi

Kehitysversio Premiumista pyörii testisaitillani, jonka alustana on Local by Flywheel. Testisaitilla on tuorein WordPress, nippu FakerPressillä generoitua sisältöä, sekalainen läjä plugineita joiden Relevanssi-yhteensopivuudesta olen kiinnostunut ja milloin mitäkin kustomointeja.

Aikaisemmin tämä kehitysversio ei ollut suoraan versionhallinnassa, vaan kopioin tiedostot aina muualle committeja varten. Muutin tätä kuitenkin hiljattain ja nykyään testisaitilla olevat tiedostot ovat suoraan versionhallinnassa.

Muutos liittyi kehitysprosessin muuttumiseen. Aikaisemmin olen tehnyt kehitystyötä suoraan Gitin master-branchissa. Se toimii enimmäkseen kun työskentelen koodin parissa yksin, mutta onhan se vähän huono tapa työskennellä. Olen pari kertaa joutunut pieniin hankaluuksiin, kun työn alla on ollut joku isompi muutos ja samalla on tullut tarve tehdä koodiin nopeasti joku pieni mutta kiireinen turvallisuus- tai toiminnallisuuspäivitys.

Nyttemmin olen ottanut asiakseni toimia kuten oikeat koodarit, eli kun lähden kehittämään jotain uutta ominaisuutta, teen siitä ensiksi issuen GitLabiin ja avaan sille uuden branchin ja merge requestin, teen muutokset branchin sisällä ja sitten mergellä kiinni masteriin kun työ on valmis.

Merge requestin käsittelyä GitLabissa.
Liian ison liitetiedoston indeksointi tuottaa 413 Request Entity Too Large -virheen, jota Relevanssi ei kuitenkaan tunnistanut virheeksi – tämä merge request paikkaa tuon ongelman.

Ensifiilikset prosessista ovat hyvät: hiemanhan tästä tulee ylimääräistä vaivaa, mutta toisaalta kyse on prosessista, jonka oppiminen kunnolla on arvokasta ja toisaalta, se mahdollistaa esimerkiksi jonkun ominaisuuden pidempiaikaisen kehittämisen, kun se on helppo laittaa syrjään tarpeen vaatiessa.

Silloin tällöin kun siltä tuntuu, kopioin tiedostot GitHubin repon puolelle ja naksuttelen sinne commitit, pääasiassa kopioiden GitLabin puolelta. Teen Git-asiat pääasiassa SourceTreellä. Osaan käyttää Gitiä komentoriviltä ja käytän muissa projekteissa paljon myös VS Coden sisäänrakennettua Git-sovellusta, mutta jos haluan – ja aika usein haluan – committiin vain osan tiedostoon tehdyistä muutoksista, osaan kyllä tehdä sen komentoriviltäkin, mutta SourceTreellä osittainen commit sujuu merkittävästi nopeammin.

(Kopiointiprosessia varten minulla on käytössä Commander One, jota en käytä mihinkään muuhun – minulla on Commander Onen kaksiruutuisessa ikkunassa koko ajan oikeat ikkunat auki ja tarvittaessa suosikeissa helposti saatavilla pari muuta prosesseihin liittyvää hakemistoa. Kyllästyin aikoinaan etsiskelemään joka kerta uudestaan Finderiin sopivia ikkunoita, enkä toisaalta ole jaksanut viritellä mitään komentorivikomentoja.)

Commander One.
Commander One on paitsi ihan näppärä tapa siirrellä tietoja kahden aina samana pysyvän hakemiston välillä, myös ilahduttava nostalgisten muistojen lähde – Norton Commander oli aikoinaan tiedostojenkäsittelyn huippua.

Uuden version julkaiseminen

Siinä vaiheessa, kun koossa on sopivasti tavaraa uuden version julkaisemiseen, on aika julkaista uusi versio. Ympäripyöreästi sanottu, mutta eipä siihen sen kummempaa heuristiikkaa ole, jos käsillä ei ole mitään akuuttia kriisiä, joka vaatisi välitöntä paikkaamista. Pyrin julkaisemaan uuden version noin kerran kuussa, paitsi kesällä.

Versionumeroinnissa yritän seurata semanttista versionumerointia, mutta olen huomannut, että minun on vähän vaikea vetää rajaa minorin ja patchin välille. Käytännössä aika iso osa julkaisemistani versioista on patcheja (eli versionumeron kolmas numero kasvaa), kun niiden pitäisi ehkä ennemmin olla minoreita (versionumeron toinen numero kasvaa).

Usein vain lisättävät uudet ominaisuudet tuntuvat aika pieniltä ja pääpaino on kaikenlaisessa korjailussa. Semver-määrittelykin liittyy enemmän julkisiin rajapintoihin ja istuu vähän huonommin lisäosakehitykseen. Relevanssin kohdalla joka tapauksessa tarkoitus on, että sekä minorit ja patchit ovat turvallisia päivityksiä ajaa vaikka automaattisesti.

Kun julkaisen uuden version, otan versionhallinnasta archive-toiminnolla ulos kaikki tiedostot sisältävän zip-paketin ja tagaan kyseisen commitin versionumeron mukaisella tagilla. Asennuspaketti siirretään Relevanssi.comin tiedostoarkistoon ja julkaistaan alustavasti lisäämällä paketin tiedot JSON-tiedostoon, jossa on listattu kaikki tiedostoarkistosta löytyvät versiot. Alustava julkaisu tarkoittaa sitä, että versio ei ole vielä asiakkaille näkyvillä, mutta sen voi kuitenkin asentaa käyttämällä tiettyä API-avainta. Tämä siksi, että paketti käy tässä vaiheessa läpi testausprosessin (josta kirjoitan oman artikkelinsa), jonka osana tarkistetaan myös, että paketissa ei ole virheitä ja että se on asennettavissa ongelmitta.

Jos testit menevät läpi, JSON-tiedostoon vaihdetaan versionumeroksi nollan sijasta oikea versio, joka avaa tiedoston kaikkien Premium-käyttäjien asennettavaksi – kunhan on voimassaoleva lisenssi ja siihen kuuluva API-avain paikoillaan Relevanssin asetuksissa. Laitan tiedoston myös ladattavaksi Relevanssin lataussivulle ja päivitän uuden version lisenssikauppaan, josta se lähtee suoraan sähköpostilla uusille asiakkaille.

JSON-tiedosto, joka hallinnoi Premiumin tiedostojenjakelua.
Tämän tiedoston muokkaaminen säätelee sitä, millaisia versioita Premiumista on asiakkaille tarjolla automaattisten päivitysten kautta.

Ilmaisversion julkaisuprosessi

Julkaisen nykyään Premiumin ja ilmaisversion uudet versiot samaan aikaan samassa tahdissa, kunhan mukana on vain molempien versioiden sisältöä. Säästyy vaivaa, kun voi tehdä yhdet release notesit. Ilmaisversion julkaisuprosessi tapahtuu siten, että GitHubissa oleviin tiedostoihin – joissa on siis mukana jo kaikki Premiumiin tehdyt commitit, jotka koskevat ilmaisversion sisältöä – täydennetään päivityksen tiedot readme-tiedostoon ja tehdään muut vastaavat huoltotoimenpiteet.

Julkaistava versio tagataan myös GitHubissa. Sitten tiedostot kopioidaan (taas Commander Onella) hakemistoon, jossa on WordPressin SVN-repon trunk eli pääkehityslinja (sama kuin Gitin master). Sitten vain svn cp trunk tags/x.x.x ja svn ci -m "tagging version x.x.x". Täällä ei siis commit-viesteillä hienostella.

SVN:n kanssa säätämistä tunnutaan kammoavan ja asiaan on kehitelty Deployerin kaltaisia ratkaisuja, jotka hoitaisivat automaattisesti julkaisun GitHubista SVN:ään, mutta Deployeriä kokeilleena olen tyytynyt käsityöhön tässä kohtaa, ei noiden kahden komennon muistaminen paljoa vaadi kun julkaisuja on kuitenkin kymmenisen vuotta tehnyt (edelleen täytyy kyllä olla tarkkana, jos on lisännyt uusia tiedostoja, niitä kun SVN ei nappaa mukaan automaattisesti).

Yhteenveto

Prosessi on aika monivaiheinen ja monimutkainen. Tästä puuttuu tosiaan kaikki testaaminen jota prosessiin kuuluu, siitä lisää toiste (testaamista käsittelevä artikkeli löytyy täältä). Voisiko prosesseja automatisoida ja helpottaa? Varmasti, en vain vielä ole nähnyt sitä vaivan arvoiseksi. Eri vaiheet eivät toistu niin usein, että hyöty automatisoinnista olisi suurta.

Prosessissa on monia kohtia, joissa voi tehdä virheitä. Tarkkuutta tämä vaatiikin, toisaalta olen pyrkinyt muotoilemaan kuviosta sellaisen, että tavallisimmat huolimattomuusvirheet jäisivät kiinni.

Jos lähtisin nyt rakentamaan koko järjestelyä tyhjästä, voi olla, että joitain vaiheita tekisin eri tavalla. Näillä kuitenkin mennään ja tyydyn hiomaan yksittäisiä kohtia paremmiksi ja toimivammiksi.

Jos aihe kiinnostaa, keskustelen mieluusti lisää joko tässä kommenteissa tai Suomen WordPress-Slackissa.

Vastaa

Sähköpostiosoitettasi ei julkaista.

This site uses Akismet to reduce spam. Learn how your comment data is processed.