Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Keskustellaan siitä, miksi CI-työkalut ja CI ovat täysin eri asioita.

Mitä kipua CI:n on tarkoitus ratkaista, mistä idea tuli, mitkä ovat viimeisimmät vahvistukset sen toimivuudesta, kuinka ymmärtää, että sinulla on käytäntö eikä vain asennettu Jenkins.

Ajatus Jatkuvasta integraatiosta raportin tekemisestä syntyi vuosi sitten, kun olin haastatteluissa ja etsin töitä. Puhuin 10-15 yrityksen kanssa, joista vain yksi pystyi vastaamaan selkeästi, mitä CI on, ja selittämään, kuinka he ymmärsivät, ettei heillä ollut sitä. Loput puhuivat käsittämätöntä hölynpölyä Jenkinsistä :) No, meillä on Jenkins, se rakentaa, CI! Raportin aikana yritän selittää, mitä Continuous Integration oikeastaan ​​on ja miksi Jenkinsillä ja vastaavilla työkaluilla on erittäin heikko suhde tähän.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Joten mitä yleensä tulee mieleen, kun kuulet sanan CI? Useimmat ihmiset ajattelevat Jenkinsiä, Gitlab CI:tä, Travisia jne.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Vaikka googlettaisimme sen, se antaa meille nämä työkalut.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Jos olet perehtynyt kysymiseen, heti työkalujen luetteloimisen jälkeen he kertovat sinulle, että CI on, kun rakennat ja suoritat testejä sitouttamispyynnössä.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Jatkuvassa integraatiossa ei ole kyse työkaluista, ei kokoonpanoista, joissa on testejä haarassa! Jatkuva integrointi on uuden koodin erittäin toistuvaa integrointia, eikä sen käyttäminen ole välttämätöntä Jenkinsin, GitLabin jne.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Ennen kuin selvitämme, miltä täysimittainen CI näyttää, sukeltakaamme ensin sen keksineiden ihmisten kontekstiin ja tuntekaa kipu, jota he yrittivät ratkaista.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Ja he ratkaisivat tiimityöskentelyn tuskan!

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Katsotaanpa esimerkkejä vaikeuksista, joita kehittäjät kohtaavat kehittyessään tiimeissä. Tässä meillä on projekti, päähaara gitissä ja kaksi kehittäjää.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Ja he menivät töihin, kuten kaikki olivat pitkään tottuneet. Otimme tehtävän suuressa suunnitelmassa, loimme ominaisuushaaran ja kirjoitimme koodin.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Yksi viimeisteli ominaisuuden nopeammin ja yhdisti sen masteriin.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Toinen tarvitsi enemmän aikaa, se sulautui myöhemmin ja päätyi konfliktiin. Nyt sen sijaan, että kirjoittaisi yrityksen tarvitsemat ominaisuudet, kehittäjä käyttää aikaa ja energiaa konfliktien ratkaisemiseen.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Mitä vaikeampaa on yhdistää ominaisuutesi yhteiseen mestariin, sitä enemmän käytämme siihen aikaa. Ja näytin tämän melko yksinkertaisella esimerkillä. Tämä on esimerkki, jossa kehittäjiä on vain 2. Kuvittele, jos 10 tai 15 tai 100 henkilöä yrityksessä kirjoittaa yhteen tietovarastoon. Tulet hulluksi ratkaisemaan kaikki nämä konfliktit.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

On hieman erilainen tapaus. Meillä on mestari ja jotkut kehittäjät tekevät jotain.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

He loivat oksan.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Yksi kuoli, kaikki oli hyvin, hän läpäisi tehtävän.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Sillä välin toinen kehittäjä luovutti tehtävänsä. Oletetaan, että hän lähetti sen tarkistettavaksi. Monilla yrityksillä on käytäntö nimeltä arvostelu. Toisaalta tämä käytäntö on hyvä ja hyödyllinen, toisaalta se hidastaa meitä monella tapaa. Emme mene siihen, mutta tässä on loistava esimerkki siitä, mihin huono arvostelutarina voi johtaa. Olet lähettänyt vetopyynnön tarkistettavaksi. Kehittäjällä ei ole enää mitään tekemistä. Mitä hän alkaa tehdä? Hän alkaa hoitaa muita tehtäviä.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Tänä aikana toinen kehittäjä teki jotain muuta.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Ensimmäinen suoritti kolmannen tehtävän.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Ja pitkän ajan kuluttua hänen arvostelunsa testattiin, ja hän yrittää sopia. Joten mitä tapahtuu? Se saa kiinni valtavan määrän konflikteja. Miksi? Koska hänen vetopyyntönsä roikkui arvostelussa, monet asiat olivat jo muuttuneet koodissa.

Konfliktitarinan lisäksi on tarina kommunikaatiosta. Kun ketjusi roikkuu tarkistuksessa, sen odottaessa jotain ja kun työskentelet ominaisuuden parissa pitkään, lakkaat seuraamasta, mitä muuta palvelusi koodikannassa muuttuu. Ehkä se, mitä yrität nyt ratkaista, ratkesi jo eilen, ja voit ottaa jonkin menetelmän ja käyttää sitä uudelleen. Mutta et näe tätä, koska työskentelet aina vanhentuneen haaran kanssa. Ja tämä vanhentunut haara johtaa aina siihen, että sinun on ratkaistava yhdistämisristiriita.

Osoittautuu, että jos työskentelemme joukkueena, eli arkistossa ei tuijota yksi, vaan 5-10 henkilöä, niin mitä kauemmin emme lisää koodiamme masteriin, sitä enemmän kärsimme, koska lopulta tarvitsemme jotain sitten yhdistä se. Ja mitä enemmän konflikteja meillä on ja mitä vanhemman version kanssa työskentelemme, sitä enemmän meillä on ongelmia.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Yhdessä tekeminen on tuskallista! Olemme aina toistemme tiellä.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Tämä ongelma havaittiin yli 20 vuotta sitten. Löysin ensimmäisen maininnan jatkuvan integroinnin harjoittamisesta äärimmäisessä ohjelmoinnissa.

Extreme Programming on ensimmäinen ketterä kehys. Sivu ilmestyi vuonna 96. Ja ajatuksena oli käyttää jonkinlaisia ​​ohjelmointikäytäntöjä, suunnittelua ja muuta, jotta kehitys olisi mahdollisimman joustavaa, jotta voimme reagoida nopeasti asiakkaidemme muutoksiin tai vaatimuksiin. Ja he alkoivat kohdata tämän 24 vuotta sitten, että jos teet jotain hyvin pitkään ja sivussa, käytät siihen enemmän aikaa, koska sinulla on konflikteja.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Nyt analysoimme ilmaisun "Jatkuva integrointi" erikseen. Jos käännämme sen suoraan, saamme jatkuvan integroinnin. Mutta kuinka jatkuva se on, ei ole kovin selvää; se on hyvin epäjatkuvaa. Mutta kuinka paljon integraatiota sillä on, ei myöskään ole kovin ilmeistä.

Ja siksi annan teille nyt lainauksia Extreme Programmingista. Ja analysoimme molemmat sanat erikseen.

Integrointi - Kuten jo sanoin, pyrimme varmistamaan, että jokainen insinööri työskentelee koodin uusimman version kanssa, jotta hän pyrkii lisäämään koodinsa mahdollisimman usein yhteiseen haaraan, jotta nämä ovat pieniä haaroja. Koska jos ne ovat suuria, voimme helposti juuttua sulautumiskonflikteihin viikoksi. Tämä pätee erityisesti, jos meillä on pitkä kehitysjakso, kuten vesiputous, jossa kehittäjä lähti kuukaudeksi leikkaamaan jotain valtavaa ominaisuutta. Ja hän on jumissa integraatiovaiheessa hyvin pitkäksi aikaa.

Integraatio on sitä, kun otamme haaramme ja integroimme sen isäntäkoneeseen, yhdistämme sen. On olemassa äärimmäinen vaihtoehto, kun olemme transbase-kehittäjä, jossa pyrimme varmistamaan, että kirjoitamme välittömästi masterille ilman ylimääräisiä haaroja.

Yleensä integrointi tarkoittaa koodin ottamista ja sen vetämistä isäntälaitteeseen.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Mitä tarkoitetaan tässä sanalla "jatkuva", mitä kutsutaan jatkuvuudeksi? Käytäntö tarkoittaa, että kehittäjä pyrkii integroimaan koodinsa mahdollisimman nopeasti. Tämä on hänen tavoitteensa suorittaessaan mitä tahansa tehtävää - saada hänen koodinsa masteriin mahdollisimman nopeasti. Ihanteellisessa maailmassa kehittäjät tekisivät tämän muutaman tunnin välein. Eli otat pienen ongelman ja yhdistät sen mestariin. Kaikki on mahtavaa. Tähän pyrit. Ja tätä pitää tehdä jatkuvasti. Heti kun teet jotain, laitat sen heti mestarille.

Ja kehittäjä, joka tekee jotain, on vastuussa siitä, mitä hän teki saadakseen sen toimimaan eikä rikkoa mitään. Tässä testitarina yleensä ilmestyy. Haluamme suorittaa joitain testejä sitoumuksellemme, yhdistämisellemme varmistaaksemme, että se toimii. Ja tässä Jenkins voi auttaa sinua.

Mutta tarinoiden kanssa: tehdään muutokset pieniksi, annetaan tehtävien olla pieniä, tehdään ongelma ja yritetään heti upottaa se jotenkin mestariin - mikään Jenkins ei auta tässä. Koska Jenkins auttaa sinua vain suorittamaan testejä.

Voit pärjätä ilman niitä. Tämä ei satuta sinua ollenkaan. Koska harjoittelun tavoitteena on mitata niin usein kuin mahdollista, jotta ei tulevaisuudessa tuhlata valtavasti aikaa konflikteihin.

Kuvitellaan, että jostain syystä elämme vuotta 2020 ilman Internetiä. Ja työskentelemme paikallisesti. Meillä ei ole Jenkinsiä. Tämä on hyvä. Voit silti mennä eteenpäin ja perustaa paikallisen sivuliikkeen. Kirjoitit siihen koodin. Saimme tehtävän valmiiksi 3-4 tunnissa. Vaihdoimme masteriksi, teimme git-vedon ja liitimme haaramme sinne. Valmis. Jos teet tämän usein, onnittelut, sinulla on jatkuva integraatio!

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Mitä todisteita nykymaailmasta on, että siihen kannattaa käyttää energiaa? Koska se on yleensä vaikeaa. Jos yrität työskennellä tällä tavalla, ymmärrät, että suunnittelu vaikuttaa nyt ja joudut käyttämään enemmän aikaa tehtävien purkamiseen. Sillä jos teet mies..., et pysty sopimaan nopeasti ja joudut siten vaikeuksiin. Sinulla ei ole enää harjoittelua.

Ja se tulee kalliiksi. Jatkuvalla integraatiolla ei ole mahdollista työskennellä heti huomenna. Teillä kaikilla kestää hyvin kauan tottua siihen, kestää hyvin kauan tottua tehtävien purkamiseen, kestää hyvin kauan tottua tarkistuskäytännön uudelleen tekemiseen, jos sinulla on sellainen . Koska tavoitteemme on, että se sulaa tänään. Ja jos teet tarkistuksen kolmen päivän kuluessa, sinulla on ongelmia ja jatkuva integrointi ei toimi sinulle.

Mutta onko meillä tällä hetkellä asiaankuuluvia todisteita, jotka kertovat meille, että tähän käytäntöön sijoittaminen on järkevää?

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Ensimmäinen asia, joka tuli mieleeni, oli State of DevOps. Tämä on tutkimus, jota kaverit ovat tehneet 7 vuoden ajan. Nyt he tekevät sen itsenäisenä organisaationa, mutta Googlen alaisuudessa.

Ja heidän vuoden 2018 tutkimuksensa osoitti korrelaation yritysten välillä, jotka yrittävät käyttää lyhytikäisiä sivukonttoreita, jotka integroituvat nopeasti, integroituvat usein ja joilla on parempia IT-suorituskykyindikaattoreita.

Mitä nämä indikaattorit ovat? Nämä ovat neljä mittaria, jotka he ottavat kaikilta yrityksiltä kyselylomakkeissaan: käyttöönottotiheys, muutosten läpimenoaika, palvelun palautusaika, muutosten epäonnistumisprosentti.

Ja ensinnäkin on tämä korrelaatio, tiedämme, että usein mittaavilla yrityksillä on paljon parempia mittareita. Ja heillä on yritysten jako useisiin luokkiin: nämä ovat hitaita yrityksiä, jotka tuottavat jotain hitaasti, keskikokoista, menestyvää ja eliittiä. Eliittiä ovat Netflix, Amazon, jotka ovat supernopeita, tekevät kaiken nopeasti, kauniisti ja tehokkaasti.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Toinen tarina, joka tapahtui vain kuukausi sitten. Technology Radarilla on loistava artikkeli Gitflowsta. Gitflow eroaa kaikista muista siinä, että sen haarat ovat pitkäikäisiä. On irrotushaaroja, jotka elävät pitkään, ja niissä on oksia, jotka elävät myös pitkään. Tämä Technology Radarin käytäntö on siirtynyt HOLD:iin. Miksi? Koska ihmiset kohtaavat integraation tuskaa.

Jos oksasi elää hyvin pitkään, se jää jumiin, mätää ja alamme viettää enemmän aikaa yrittääksemme tehdä siihen jonkinlaisen muutoksen.

Ja äskettäin Gitflown kirjoittaja sanoi, että jos tavoitteesi on jatkuva integraatio, jos tavoitteesi on, että haluat rullata niin usein kuin mahdollista, Gitflow on huono idea. Hän lisäsi artikkeliin erikseen, että jos sinulla on taustajärjestelmä, jossa voit pyrkiä tähän, niin Gitflow on sinulle tarpeeton, koska Gitflow hidastaa sinua, Gitflow aiheuttaa sinulle ongelmia integraation kanssa.

Tämä ei tarkoita, että Gitflow on huono eikä sitä pitäisi käyttää. Se on muihin tilanteisiin. Esimerkiksi silloin, kun tarvitset useita palvelun tai sovelluksen versioita, eli kun tarvitset tukea pitkäksi aikaa.

Mutta jos keskustelet ihmisten kanssa, jotka tukevat tällaisia ​​palveluita, kuulet paljon tuskaa siitä, että tämä versio oli 3.2, joka oli 4 kuukautta sitten, mutta tätä korjausta ei sisällytetty siihen ja nyt sen tekemiseksi sinun on tehtävä joukko muutoksia. Ja nyt ne ovat taas jumissa, ja nyt he ovat pyöritelleet viikon ajan yrittäessään ottaa käyttöön jotain uutta ominaisuutta.

Kuten Alexander Kovalev oikein totesi chatissa, korrelaatio ei ole sama asia kuin syy-yhteys. Tämä on totta. Toisin sanoen ei ole suoraa yhteyttä siihen, että jos sinulla on jatkuva integrointi, kaikki mittarit ovat mahtavia. Mutta on olemassa positiivinen korrelaatio, että jos toinen on yksi, niin todennäköisesti myös toinen. Ei fakta, mutta mitä todennäköisimmin. Se on vain korrelaatio.

Jatkuva integraatio käytäntönä, ei Jenkins. Andrei Aleksandrov

Näyttää siltä, ​​​​että olemme jo tekemässä jotain, näyttää siltä, ​​​​että olemme jo sulautumassa, mutta kuinka voimme ymmärtää, että meillä on edelleen Jatkuva integraatio, että sulaudumme melko usein?

Jez Humble on käsikirjan, Acceleraten, Continuous Delivery -sivuston ja kirjan Continuous Delivery kirjoittaja. Hän tarjoaa tämän testin:

  • Insinöörin koodi saa päällikön joka päivä.
  • Suorita jokaiselle sitoumukselle yksikkötestit.
  • Masterin rakenne putosi, se korjattiin noin 10 minuutissa.

Hän ehdottaa tällaisen testin käyttämistä varmistaaksesi, että sinulla on tarpeeksi harjoittelua.

Minusta jälkimmäinen on hieman kiistanalainen. Eli jos voit korjata sen 10 minuutissa, sinulla on jatkuva integrointi, se kuulostaa mielestäni hieman oudolta, mutta se on järkevää. Miksi? Koska jos jäädyt usein, se tarkoittaa, että muutokset ovat pieniä. Jos pieni muutos tarkoittaa, että perusversiosi on rikki, voit löytää esimerkin nopeasti, koska muutos on pieni. Tässä teillä oli pieni yhdistäminen, 20-30 riviä siinä muuttui. Ja vastaavasti voit nopeasti ymmärtää, mikä syy oli, koska muutokset ovat pieniä, sinulla on hyvin pieni alue etsiä ongelmaa.

Ja vaikka tuote hajoaisi julkaisun jälkeen, niin jos meillä on jatkuvan integroinnin käytäntö, meidän on paljon helpompi toimia, koska muutokset ovat pieniä. Kyllä tämä vaikuttaa suunnitteluun. Tämä sattuu. Ja luultavasti vaikeinta tässä käytännössä on tottua tehtävien purkamiseen eli miten se tehdään niin, että voit ottaa jotain ja tehdä sen muutamassa tunnissa ja samalla läpäistä arvostelun, jos sinulla on yksi. Arvostelu on erillinen kipu.

Yksikkötestit ovat vain apulainen, joka auttaa sinua ymmärtämään, onnistuiko integraatiosi ja onko mikään mennyt rikki. Mielestäni tämä ei myöskään ole täysin pakollista, koska tämä ei ole käytännön tarkoitus.

Tämä on lyhyt johdatus jatkuvaan integrointiin. Siinä on kaikki tähän käytäntöön. Olen valmis kysymyksiin.

Teen vielä lyhyesti yhteenvedon:

  • Jatkuva integrointi ei ole Jenkins, se ei ole Gitlab.
  • Tämä ei ole työkalu, se on käytäntö, että yhdistämme koodimme masteriin niin usein kuin mahdollista.
  • Teemme tämän välttääksemme sitä valtavaa kipua, joka syntyy sulautumisista tulevaisuudessa, eli koemme hieman kipua nyt, jotta emme kokisi enempää tulevaisuudessa. Se on koko pointti.
  • Sivulla on viestintää koodin kautta, mutta näen tätä erittäin harvoin, mutta myös tähän se on suunniteltu.

kysymykset

Mitä tehdä hajoamattomille tehtäville?

Hajoaa. Mikä on ongelma? Voitko antaa esimerkin, että on olemassa tehtävä, jota ei ole hajotettu?

On tehtäviä, joita ei voida hajottaa sanasta "täysin", esimerkiksi sellaisia, jotka vaativat erittäin syvää asiantuntemusta ja jotka voidaan itse asiassa ratkaista kuukauden kuluessa jonkin sulavan tuloksen saavuttamiseksi.

Jos ymmärrän sinut oikein, niin kyseessä on suuri ja monimutkainen tehtävä, jonka tulos näkyy vasta kuukauden kuluttua?

Kyllä se on oikein. Kyllä, tulos on mahdollista arvioida aikaisintaan kuukauden kuluttua.

Hieno. Yleisesti ottaen tämä ei ole ongelma. Miksi? Koska tässä tapauksessa, kun puhumme oksista, emme puhu oksasta, jossa on ominaisuus. Ominaisuudet voivat olla suuria ja monimutkaisia. Ne voivat vaikuttaa useisiin komponentteihin. Ja ehkä emme voi tehdä niitä kokonaan yhdessä haarassa. Tämä on hyvä. Meidän täytyy vain murtaa tämä tarina. Jos ominaisuus ei ole täysin valmis, tämä ei tarkoita, että joitain sen koodin osia ei voitaisi yhdistää. Lisäsit esimerkiksi siirron, ja ominaisuuden sisällä on joitain vaiheita. Oletetaan, että sinulla on vaihe – tee siirto, lisää uusi menetelmä. Ja näitä voi jo mitata joka päivä.

Hieno. Mitä järkeä sitten on?

Mitä järkeä on tappaa pieniä asioita joka päivä?

Kyllä.

Jos he rikkovat jotain, näet sen heti. Sinulla on pieni pala, joka on rikkonut jotain, sinun on helpompi korjata se. Asia on siinä, että pienen palan yhdistäminen nyt on paljon helpompaa kuin suuren yhdistäminen muutamassa viikossa. Ja kolmas kohta on, että muut insinöörit työskentelevät koodin nykyisen version kanssa. He näkevät, että tänne on lisätty joitain siirtoja, ja sitten on ilmestynyt jokin menetelmä, jota he saattavat myös haluta käyttää. Kaikki näkevät, mitä koodissasi tapahtuu. Näitä kolmea asiaa varten harjoitellaan.

Kiitos, asia on suljettu!

(Oleg Soroka) Saanko lisätä? Sanoit kaiken oikein, haluan vain lisätä yhden lauseen.

So.

Jatkuvassa integroinnissa koodi yhdistetään yhteiseksi haaraksi ei silloin, kun ominaisuus on täysin valmis, vaan kun koontiversio lakkaa rikkoutumasta. Ja voit turvallisesti sitoutua masteroimaan niin monta kertaa päivässä kuin haluat. Toinen näkökohta on, että jos et jostain syystä voi jakaa kuukausittaista tehtävää tehtäviin vähintään kolmeksi päiväksi, olen hiljaa noin kolme tuntia, sinulla on valtava ongelma. Ja se, että sinulla ei ole jatkuvaa integraatiota, on pienin näistä ongelmista. Tämä tarkoittaa, että sinulla on ongelmia arkkitehtuurin ja nollatekniikan kanssa. Sillä vaikka tämä on tutkimusta, se on joka tapauksessa muotoiltava hypoteesien tai syklin muodossa.

Puhuimme neljästä mittarista, jotka erottavat menestyvät yritykset jälkeen jääneistä. Meidän on vielä elettävä nähdäksemme nämä neljä mittaria. Jos keskimääräinen tehtäväsi suorittaminen kestää kuukauden, keskityn ensin tähän mittariin. Ensin laskisin sen 4 päivään. Ja sen jälkeen aloin miettiä Continuousta.

Ymmärsinkö oikein, että mielestäsi suunnittelukäytäntöihin ei yleensä kannata panostaa, jos minkä tahansa tehtävän suorittaminen kestää kuukauden?

Sinulla on jatkuva integraatio. Ja on sellainen aihe, että 10 minuutissa voit joko korjata korjauksen tai peruuttaa sen. Kuvittele, että vierität sen. Lisäksi sinulla on jopa jatkuva käyttöönotto, otit sen käyttöön ja vasta sitten huomasit, että jokin meni pieleen. Ja sinun on palautettava se, mutta olet jo siirtänyt tietokantasi. Sinulla on jo seuraavan version tietokantaskeema, lisäksi sinulla oli myös jonkinlainen varmuuskopio ja sinne kirjoitettiin myös tiedot.

Ja mikä vaihtoehto sinulla on? Jos peruutat koodin, se ei enää toimi tämän päivitetyn tietokannan kanssa.

Pohja liikkuu vain eteenpäin, kyllä.

Ihmiset, joilla on huonot insinöörikäytännöt, eivät todennäköisesti ole myöskään lukeneet paksua kirjaa aiheesta.... Mitä tehdä varmuuskopiolle? Jos palautat varmuuskopiosta, se tarkoittaa, että menetät sillä hetkellä keräämäsi tiedot. Esimerkiksi tietokannan uuden version kanssa työskentelimme kolme tuntia, sinne rekisteröityneet käyttäjät. Kieltäydyt vanhasta varmuuskopiosta, koska järjestelmä ei toimi uuden version kanssa, joten olet menettänyt nämä käyttäjät. Ja he ovat tyytymättömiä, he vannovat.

Jotta voit hallita täyden valikoiman käytäntöjä, jotka tukevat jatkuvaa integrointia ja jatkuvaa toimitusta, ei riitä, että oppii vain kirjoittamaan.... Ensinnäkin niitä voi olla paljon, se on epäkäytännöllistä. Lisäksi on joukko muita käytäntöjä, kuten Scientific. On olemassa tällainen käytäntö, GitHub suosi sitä aikoinaan. Tämä on silloin, kun sinulla on sekä vanha että uusi koodi käynnissä samanaikaisesti. Tämä on silloin, kun teet keskeneräisen ominaisuuden, mutta se voi palauttaa jonkin arvon: joko funktiona tai Rest API:na. Suoritat sekä uuden koodin että vanhan koodin ja vertaat niiden välistä eroa. Ja jos on eroa, kirjaa tämä tapahtuma. Näin tiedät, että sinulla on uusi ominaisuus valmiina ottamaan käyttöön vanhan päälle, jos näiden kahden välillä ei ole ollut ristiriitaa tiettyyn aikaan.

Tällaisia ​​käytäntöjä on satoja. Suosittelen aloittamaan transbase-kehityksestä. Hän ei ole 100 % jatkuvassa integraatiossa, mutta käytännöt ovat samat, ilman toista ei voi elää hyvin.

Annoitko transbase-kehityksen esimerkkinä, jossa voit nähdä käytäntöjä, vai ehdotatko, että ihmiset alkaisivat käyttää transbase-kehitystä?

Katso, koska he eivät voi käyttää sitä. Jotta voit käyttää niitä, sinun on luettava paljon asioita. Ja kun henkilö kysyy: "Mitä tehdä ominaisuudella, joka kestää kuukauden, se tarkoittaa, että hän ei ole lukenut transbase-kehityksestä." En suosittele sitä vielä. Suosittelen keskittymään pelkästään aiheeseen, kuinka suuret tehtävät jaetaan arkkitehtonisesti oikein pienemmiksi. Tämä on hajoamisen ydin.

Hajoaminen on yksi arkkitehdin työkaluista. Teemme ensin analyysin, sitten hajotuksen, sitten synteesin ja sitten integroinnin. Ja näin kaikki toimii meillä. Ja meidän on vielä kasvattava jatkuvaan integraatioon hajoamisen kautta. Ensimmäisessä vaiheessa herää kysymyksiä, ja puhumme jo neljännestä, eli mitä useammin teemme integraatiota, sen parempi. On vielä liian aikaista tehdä tämä; olisi mukavaa leikata ensin monoliittisi.

Sinun on piirrettävä joukko nuolia ja neliöitä johonkin kaavioon. Et voi sanoa, että nyt näytän uuden sovelluksen arkkitehtuurikaavion ja näytän yhden neliön, jonka sisällä on vihreä painike sovellukselle. Joka tapauksessa neliöitä ja nuolia tulee lisää. Jokaisessa näkemässäni kaaviossa oli enemmän kuin yksi. Ja hajoamista, jopa graafisen esityksen tasolla, tapahtuu jo. Siksi neliöt voidaan tehdä itsenäisiksi. Jos ei, niin minulla on suuria kysymyksiä arkkitehdille.

Chatista tulee kysymys: "Jos tarkistus on pakollinen ja kestää kauan, ehkä päivän tai enemmän?"

Sinulla on ongelmia harjoituksen kanssa. Tarkastuksen ei pitäisi kestää päivää tai pidempään. Tämä on sama tarina kuin edellisessä kysymyksessä, vain hieman pehmeämpi. Jos tarkastelu jatkuu päivän, tämä tarkastelu on todennäköisesti menossa johonkin erittäin suureen muutokseen. Tämä tarkoittaa, että se on pienennettävä. Transbase-kehityksessä, jota Oleg suositteli, on tarina nimeltä jatkuva tarkistus. Hänen ideansa on, että teemme tällaisen pienen vetopyynnön tarkoituksella, koska pyrimme sulautumaan jatkuvasti ja vähän kerrallaan. Ja niin vetopyyntö muuttaa yhden abstraktion tai 10 riviä. Tämän arvostelun ansiosta se vie meiltä muutaman minuutin.

Jos tarkistus kestää päivän tai enemmän, jokin on vialla. Ensinnäkin sinulla voi olla ongelmia arkkitehtuurissa. Tai tämä on iso koodinpätkä, esimerkiksi 1 riviä. Tai arkkitehtuurisi on niin monimutkainen, ettei kukaan ymmärrä sitä. Tämä on hieman sivusuuntainen ongelma, mutta se on myös ratkaistava. Ehkä arvostelua ei tarvita ollenkaan. Meidän on myös mietittävä tätä. Arvostelu on asia, joka hidastaa sinua. Sillä on yleisesti ottaen etunsa, mutta sinun on ymmärrettävä, miksi teet sen. Onko tämä tapa, jolla voit nopeasti välittää tietoa, onko tämä tapa asettaa joitain standardeja sisäisesti vai mitä? Miksi tarvitset tätä? Koska tarkistus on tehtävä joko hyvin nopeasti tai peruutettava kokonaan. Se on kuin transbase-kehitys - tarina on erittäin kaunis, mutta vain aikuisille miehille.

Mitä tulee neljään mittariin, suosittelen silti niiden poistamista ymmärtääksesi, mihin tämä johtaa. Katso numeroita, katso kuvaa, kuinka huonosti kaikki on.

(Dmitry) Olen valmis aloittamaan keskustelun tästä kanssasi. Numerot ja mittarit ovat hienoja, käytännöt ovat mahtavia. Mutta sinun on ymmärrettävä, tarvitseeko yritys sitä. On yrityksiä, jotka eivät tarvitse tällaista muutosnopeutta. Tiedän yrityksiä, joissa muutoksia ei voi tehdä 15 minuutin välein. Eikä siksi, että ne olisivat niin huonoja. Tämä on sellainen elinkaari. Ja jotta voit tehdä oksat -ominaisuuden, vaihtoominaisuuden, tarvitset syvällistä tietoa.

Se on monimutkaista. Jos haluat lukea tarinan vaihtoominaisuudesta tarkemmin, suosittelen sitä https://trunkbaseddevelopment.com/. Ja Martin Fowler on upea artikkeli vaihto-ominaisuuksista: mitä tyyppejä on olemassa, elinkaari jne. Vaihtotoiminto on monimutkainen.

Etkä ole vieläkään vastannut kysymykseen: "Tarvitaanko Jenkinsiä vai ei?"

Jenkinsiä ei todellakaan tarvita missään tapauksessa. Mutta tosissaan, työkalut: Jenkins, Gitlab tuovat sinulle mukavuutta. Näet, että kokoonpano on koottu vai ei. He voivat auttaa sinua, mutta ne eivät anna sinulle harjoittelua. He voivat antaa sinulle vain ympyrän - Ok, ei Ok. Ja sitten, jos kirjoitat myös testejä, koska jos testejä ei ole, se on melkein turhaa. Siksi sitä tarvitaan, koska se on kätevämpää, mutta yleensä voit elää ilman sitä, et menetä paljon.

Eli jos sinulla on käytäntöjä, tarkoittaako se, että et tarvitse sitä?

Oikein. Suosittelen Jez Humblen testiä. Siinä minulla on kaksijakoinen asenne viimeiseen kohtaan. Mutta yleensä, jos sinulla on kolme asiaa, yhdistät jatkuvasti, testaat committeja masterissa, korjaat nopeasti koontiversion masterissa, niin et ehkä tarvitse mitään muuta.

Kun odotamme osallistujien kysymyksiä, minulla on kysymys. Puhuimme vain tuotekoodista. Oletko käyttänyt sitä infrastruktuurikoodiin? Onko se sama koodi, onko sillä samat periaatteet ja sama elinkaari, vai onko olemassa erilaisia ​​elinkaareja ja periaatteita? Yleensä, kun kaikki puhuvat jatkuvasta integraatiosta ja kehittämisestä, kaikki unohtavat, että olemassa on myös infrastruktuurikoodi. Ja viime aikoina sitä on ollut enemmän ja enemmän. Ja pitäisikö kaikki nämä säännöt tuoda sinne?

Ei edes sitä, että sen pitäisi olla, se olisi hienoa, koska se helpottaisi elämää samalla tavalla. Heti kun työskentelemme koodin kanssa, emme bash-skriptien kanssa, mutta meillä on normaali koodi.

Stop, stop, bash-skripti on myös koodi. Älä koske vanhaan rakkaani.

Okei, en talla muistojasi. Inhoan bashia henkilökohtaisesti. Se rikkoo rumaa ja pelottavaa koko ajan. Ja se katkeaa usein arvaamattomasti, minkä vuoksi en pidä siitä. Mutta okei, oletetaan, että sinulla on bash-koodi. Ehkä en todellakaan ymmärrä, ja siellä on normaalit testauskehykset. En vain ole perillä. Ja saamme samat edut.

Heti kun käsittelemme infrastruktuuria koodina, saamme kaikki samat ongelmat kuin kehittäjät. Muutama kuukausi sitten törmäsin tilanteeseen, jossa kollega lähetti minulle vetopyynnön 1 000 rivistä bashissa. Ja vietät aikaa arvostelussa 4 tuntia. Samat ongelmat syntyvät. Se on edelleen koodi. Ja se on edelleen yhteistyötä. Jäämme jumiin vetopyyntöön ja jäämme kiinni siihen tosiasiaan, että esimerkiksi ratkaisemme samat yhdistämisristiriidat samassa bashissa.

Katselen nyt erittäin aktiivisesti tätä koko asiaa kauneimman infra-ohjelmoinnin parissa. Olen nyt tuonut Pulumin infrastruktuuriin. Tämä on ohjelmointia puhtaimmassa muodossaan. Siellä se on vielä mukavampaa, koska minulla on kaikki ohjelmointikielen ominaisuudet, eli tein kauniin kytkimen sinisestä samoilla jos:illa ja kaikki on hyvin. Eli muutokseni on jo mestarissa. Kaikki voivat jo nähdä hänet. Muut insinöörit tietävät sen. Siellä se on jo vaikuttanut johonkin. Se ei kuitenkaan ollut käytössä kaikissa infrastruktuureissa. Se käynnistyi esimerkiksi testipenkeissäni. Siksi on välttämätöntä vastata kysymykseesi uudelleen. Se helpottaa meidän, koodin kanssa työskentelevien insinöörien, elämää samalla tavalla.

Jos jollain muulla on kysyttävää?

Minulla on kysymys. Haluan jatkaa keskustelua Olegin kanssa. Yleisesti ottaen olen sitä mieltä, että olet oikeassa, että jos tehtävän suorittaminen kestää kuukauden, sinulla on ongelma arkkitehtuurissa, sinulla on ongelma analysoinnissa, hajotuksessa, suunnittelussa jne. Mutta minulla on tunne, että jos aloitat yrittää elää Jatkuvan Integraation mukaan, niin alat korjata kipua suunnittelulla, koska et pääse siitä eroon missään muualla.

(Oleg) Kyllä, niin on. Tämä käytäntö on verrattavissa mihin tahansa muuhun vakavaan kulttuuria muuttavaan käytäntöön. Vaikeimmin voitettavaa ovat tottumukset, erityisesti huonot tavat. Ja jos tämän käytännön toteuttamiseksi tarvitaan vakava muutos ympärilläsi olevien tottumuksiin: kehittäjät, johto, tuotantopäällikkö, niin yllätykset odottavat sinua.

Mitä yllätyksiä voi olla? Oletetaan, että päätät integroitua useammin. Ja sinulla on joitain muita integraatioon liittyviä asioita, esimerkiksi esineitä. Ja esimerkiksi yrityksessäsi on käytäntö, että jokainen artefakti on kirjattava jollakin tavalla jonkinlaiseen esineiden säilytysjärjestelmään. Ja se vie jonkin aikaa. Henkilön on valittava valintaruutu, että hän on julkaisupäällikkönä testannut tämän artefaktin varmistaakseen, että se on valmis julkaistavaksi tuotannossa. Jos se vie 5-10-15 minuuttia, mutta teet layoutin kerran viikossa, niin puolen tunnin käyttäminen kerran viikossa on pieni vero.

Jos teet jatkuvan integroinnin 10 kertaa päivässä, 10 kertaa on kerrottava 30 minuutilla. Ja tämä ylittää tämän julkaisupäällikön työajan. Hän vain kyllästyy tekemään sitä. Joistakin harjoituksista on kiinteät kustannukset. Siinä kaikki.

Ja sinun on joko peruutettava tämä sääntö, jotta et enää tee sellaista roskaa, eli et määritä manuaalisesti tutkintoa vastaamaan jotakin. Luotat täysin joihinkin automatisoituihin valmiustesteihin.

Ja jos tarvitset todisteita joltakulta, jotta pomo allekirjoittaa sen, etkä pääse tuotantoon ilman, että Vasya sanoo, että hän sallii sen jne. - kaikki tämä hölynpöly tulee harjoittajan tielle. Koska jos veroon liittyy joitain toimintoja, niin kaikki kasvaa 100-kertaiseksi. Siksi kaikki eivät useinkaan ota vuoroa ilolla vastaan. Koska ihmisten tapoja on vaikea muuttaa.

Kun ihminen tekee tavanomaista työtään, hän tekee sen melkein ajattelematta. Hänen kognitiivinen kuormituksensa on nolla. Hän vain leikkii sillä, hänellä on jo muistilista päässään, hän on tehnyt sen tuhat kertaa. Ja heti kun tulet sanomaan hänelle: "Perutetaan tämä harjoitus ja otetaan käyttöön uusi maanantaista alkaen", siitä tulee hänelle voimakas kognitiivinen kuormitus. Ja se tulee kaikille kerralla.

Siksi yksinkertaisin asia, vaikka kaikilla ei ole varaa tähän ylellisyyteen, mutta näin teen aina, tämä on seuraava. Jos uusi projekti alkaa, niin yleensä kaikki testaamattomat käytännöt ahdataan heti tähän projektiin. Vaikka projekti on nuori, emme todellakaan riskeeraa mitään. Prodia ei vielä ole, ei ole mitään tuhottavaa. Siksi sitä voidaan käyttää koulutuksena. Tämä lähestymistapa toimii. Mutta kaikilla yrityksillä ei ole mahdollisuutta aloittaa tällaisia ​​hankkeita usein. Vaikka tämä on myös hieman outoa, koska nyt on käynnissä täydellinen digitaalinen muutos, jokaisen on käynnistettävä kokeita pysyäkseen kilpailijoiden tahdissa.

Tässä tulet siihen tulokseen, että sinun on ensin ymmärrettävä, mitä sinun on tehtävä. Maailma ei ole ihanteellinen, eikä tuote myöskään ole ihanteellinen.

Kyllä nämä asiat liittyvät toisiinsa.

Yritykset eivät myöskään aina ymmärrä, että heidän täytyy mennä näin.

On tilanne, jossa muutokset eivät ole ollenkaan mahdollisia. Tämä on tilanne, jossa joukkueella on enemmän paineita. Joukkue on jo aika loppuun palanut. Hänellä ei ole vapaa-aikaa mihinkään kokeiluun. He työskentelevät ominaisuuksien parissa aamusta iltaan. Ja hallinnassa on yhä vähemmän ominaisuuksia. Tarvitaan yhä enemmän. Tällaisessa tilanteessa muutokset eivät ole lainkaan mahdollisia. Tiimille voidaan sanoa vain, että huomenna teemme samoin kuin eilen, meidän on vain tehtävä vähän enemmän ominaisuuksia. Tässä mielessä siirtyminen mihinkään käytäntöön ei ole mahdollista. Tämä on klassinen tilanne, kun ei ole aikaa teroittaa kirvettä, puita on kaadettava, joten ne leikataan tylsällä kirveellä. Tässä ei ole yksinkertaisia ​​​​vinkkejä.

(Dmitry) Luen selvennyksen chatista: "Mutta tarvitsemme paljon testikattavuutta eri tasoilla. Kuinka paljon aikaa on varattu testeihin? Se on vähän kallis ja vie paljon aikaa."

(Oleg) Tämä on klassinen väärinkäsitys. Testejä pitäisi olla tarpeeksi, jotta voit olla varma. Jatkuva integrointi ei ole asia, jossa 100% testeistä tehdään ensin ja vasta sitten aletaan soveltaa tätä käytäntöä. Jatkuva integraatio vähentää kognitiivista kuormitustasi, koska jokainen silmilläsi näkemäsi muutos on niin ilmeinen, että ymmärrät, rikkooko se jotain vai ei, jopa ilman testejä. Voit testata tätä nopeasti päässäsi, koska muutokset ovat pieniä. Vaikka sinulla olisi vain manuaalisia testaajia, se on myös heille helpompaa. Rullasit ulos ja sanoit: "Katso, onko jokin rikki?" He tarkistivat ja sanoivat: "Ei, mikään ei ole rikki." Koska testaaja tietää, mistä etsiä. Sinulla on yksi sitoumus, joka liittyy yhteen koodinpalaan. Ja tätä käytetään hyväksi tietyllä käytöksellä.

Täällä olet tietysti koristellut.

(Dmitry) En ole samaa mieltä. On olemassa käytäntö - testivetoinen kehitys, joka säästää sinut tästä.

(Oleg) No, en ole vielä päässyt siihen pisteeseen. Ensimmäinen illuusio on, että sinun on kirjoitettava 100% testeistä tai sinun ei tarvitse tehdä jatkuvaa integrointia ollenkaan. Se ei ole totta. Nämä ovat kaksi rinnakkaista käytäntöä. Ja he eivät ole suoraan riippuvaisia. Testin kattavuuden tulee olla optimaalinen. Optimaalinen - tämä tarkoittaa, että olet itse varma, että päällikön laatu, jossa isäntäsi pysyi sitoutumisen jälkeen, antaa sinun painaa luottavaisesti "Ota käyttöön" -painiketta humalassa perjantai-iltana. Miten saavutat tämän? Tarkastelun, kattavuuden, hyvän seurannan kautta.

Hyvää seurantaa ei voi erottaa testeistä. Jos suoritat testit kerran pre-prodissa, he tarkistavat kaikki käyttäjäskriptit kerran ja siinä se. Ja jos käytät niitä loputtomassa silmukassa, tämä on käytössäsi oleva valvontajärjestelmä, joka testaa loputtomasti kaikkea - kaatuipa se vai ei. Tässä tapauksessa ero on vain siinä, tehdäänkö se kerran vai kahdesti. Erittäin hyvä joukko testejä... käynnissä loputtomasti, tämä on valvontaa. Ja oikean seurannan pitäisi olla tällaista.

Ja siksi, kuinka tarkalleen saavutat tämän tilan, kun valmistaudut perjantai-iltana ja menet kotiin, on toinen kysymys. Ehkä olet vain rohkea paskiainen.

Palataan hieman takaisin jatkuvaan integraatioon. Juoksimme hieman erilaiseen monimutkaiseen käytäntöön.

Ja toinen illuusio on, että MVP, heidän mukaansa, on tehtävä nopeasti, joten testejä ei tarvita siellä ollenkaan. Ei varmasti sillä tavalla. Tosiasia on, että kun kirjoitat käyttäjätarinan MVP:hen, voit joko kehittää sen palloon, eli kuulit, että siellä oli jonkinlainen käyttäjätarina ja juoksit heti koodaamaan sitä, tai voit työskennellä TDD: llä. Ja TDD:n mukaan, kuten käytäntö osoittaa, se ei vie pidempään, eli testit ovat sivuvaikutus. TDD:n käytäntö ei ole testaamista. Huolimatta siitä, mitä kutsutaan testivetoiseksi kehitykseksi, kyse ei ole ollenkaan testeistä. Tämä on myös pikemminkin arkkitehtoninen lähestymistapa. Tämä on lähestymistapa kirjoittaa juuri sitä, mitä tarvitaan, ja olla kirjoittamatta sitä, mitä ei tarvita. Tämä on käytäntö, jossa keskitytään ajattelusi seuraavaan iteraatioon sovellusarkkitehtuurin luomisessa.

Siksi näistä illuusioista ei ole niin helppoa päästä eroon. MVP ja testit eivät ole ristiriidassa keskenään. Jopa pikemminkin päinvastoin, jos teet MVP:n TDD-harjoittelulla, teet sen paremmin ja nopeammin kuin jos teet sen ilman harjoittelua, vaan pallolla.

Tämä on hyvin epäselvä ja monimutkainen ajatus. Kun kuulet, että nyt kirjoitan lisää testejä ja samalla teen jotain nopeammin, kuulostaa aivan riittämättömältä.

(Dmitry) Monet ihmiset täällä, kun he kutsuvat MVP:tä, ihmiset ovat liian laiskoja kirjoittamaan jotain normaalia. Ja nämä ovat silti eri asioita. MVP:tä ei tarvitse muuttaa huonoksi asiaksi, joka ei toimi.

Kyllä, kyllä, olet oikeassa.

Ja sitten yhtäkkiä tuotannon MVP.

Ikuisesti.

Ja TDD kuulostaa erittäin epätavalliselta, kun kuulet, että kirjoitat testejä ja näytät tekevän enemmän työtä. Se kuulostaa hyvin oudolta, mutta itse asiassa se tulee tällä tavalla nopeammaksi ja kauniimmaksi. Kun kirjoitat testiä, mietit jo paljon päässäsi, mitä koodia kutsutaan ja miten, sekä mitä käyttäytymistä siltä odotamme. Et vain sano, että kirjoitin jonkin funktion ja se tekee jotain. Aluksi luulit, että hänellä on sellaisia ​​​​ja sellaisia ​​​​olosuhteita, häntä kutsutaan sellaisella ja sellaisella tavalla. Peität tämän testeillä ja ymmärrät tämän perusteella, miltä käyttöliittymäsi näyttävät koodisi sisällä. Tällä on valtava vaikutus arkkitehtuuriin. Koodistasi tulee automaattisesti modulaarisempi, koska yrität ensin ymmärtää, miten testaat sen, ja vasta sitten kirjoitat sen.

Minulle tapahtui TDD:n kanssa se, että palkkasin jossain vaiheessa Ruby-mentorin ollessani vielä Ruby-ohjelmoija. Ja hän sanoo: "Tehdään se TDD:n mukaan." Ajattelin: "Hitto, nyt minun on kirjoitettava jotain ylimääräistä." Ja sovimme, että kahden viikon sisällä kirjoitan kaiken toimivan koodin Pythonissa TDD:n avulla. Kahden viikon jälkeen tajusin, että en halunnut palata. Kun olet yrittänyt soveltaa tätä kaikkialla kaksi viikkoa, ymmärrät, kuinka paljon helpompaa sinun on edes ajatella. Mutta tämä ei ole itsestään selvää, joten suosittelen kaikille, että jos sinulla on tunne, että TDD on vaikeaa, aikaa vievää ja tarpeetonta, kokeile pysyä siinä vain kaksi viikkoa. Kaksi riitti minulle.

(Dmitry) Voimme laajentaa tätä ajatusta infrastruktuurin toiminnan näkökulmasta. Ennen kuin lanseeraamme mitään uutta, teemme seurantaa ja käynnistämme sitten. Tässä tapauksessa valvonnasta tulee meille normaalia testausta. Ja kehitystä tapahtuu seurannan kautta. Mutta melkein kaikki sanovat, että se on pitkä, olen laiska, tein väliaikaisen luonnoksen. Jos olemme tehneet normaalia valvontaa, ymmärrämme CI-järjestelmän tilan. Ja CI-järjestelmässä on paljon valvontaa. Ymmärrämme järjestelmän tilan, ymmärrämme mitä sen sisällä on. Ja kehityksen aikana teemme vain järjestelmää niin, että se saavuttaa halutun tilan.

Nämä käytännöt ovat olleet tiedossa jo pitkään. Keskustelimme tästä noin 4 vuotta sitten. Mutta 4 vuodessa käytännössä mikään ei ole muuttunut.

Mutta tässä huomautuksessa ehdotan virallisen keskustelun lopettamista.

Video (lisätty mediaelementiksi, mutta jostain syystä ei toimi):

https://youtu.be/zZ3qXVN3Oic

Lähde: will.com

Lisää kommentti