GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi

GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi
Vieraileva kehittäjätyökalumme Pantheonissa puhuu WordPressin käyttöönottojen automatisoinnista GitLab CI/CD:llä.

В Pantheon Työskentelen kehittäjäsuhteissa, joten etsin jatkuvasti uusia tapoja auttaa WordPress- ja Drupal-kehittäjiä ratkaisemaan automaatioongelmia työnkuluissaan. Tätä varten haluan kokeilla uusia työkaluja ja yhdistää niitä keskenään toimimaan tehokkaasti.

Näen usein kehittäjien kamppailevan yhden välityspalvelimen kanssa.

On niin ilo odottaa vuoroasi käyttää välipalvelinta tai lähettää asiakkaille URL-osoite, jossa on huomautus: "Katso tästä, mutta älä vielä katso täältä."

Multidev-ympäristöt - yksi hienoista Pantheon-työkaluista - ratkaisee tämän ongelman, koska niiden avulla voit luoda ympäristöjä Git-haaroihin pyynnöstä. Jokaisella multidev-ympäristöllä on oma URL-osoite ja tietokanta, joten kehittäjät voivat työskennellä hiljaa, tarkistaa laatua ja saada hyväksynnän astumatta toistensa varpaille.

Mutta Pantheonilla ei ole työkaluja versionhallintaan tai jatkuvaan integrointiin ja käyttöönottoon (CI/CD). Mutta se on joustava alusta, johon voit integroida mitä tahansa työkaluja.

Huomasin myös, että tiimit käyttävät tiettyjä työkaluja kehittämiseen ja eri työkaluja kokoonpanoon ja käyttöönottoon.

Heillä on esimerkiksi erilaisia ​​työkaluja versionhallintaan ja CI/CD:hen. Sinun on heiluttava ja vaihdettava työkalujen välillä muokataksesi koodia ja diagnosoidaksesi ongelmia.

Päälle GitLab siellä on täysi joukko kehitystyökaluja: versionhallintaa, lippuja, yhdistämispyyntöjä, luokkansa paras CI/CD-putkisto, konttirekisteri ja kaikkea muuta vastaavaa. En ole vielä törmännyt sovellukseen, joka tarjoaa niin paljon kehitystyön hallintaan.

Rakastan automaatiota, joten opin yhdistämään Pantheonin GitLabiin niin, että GitLabin päähaaraan tehdyt sitoumukset otetaan käyttöön Pantheonin pääkehitysympäristössä. Ja GitLabin yhdistämispyynnöt voivat luoda ja ottaa käyttöön koodia Pantheonin multidev-ympäristöihin.

Tässä opetusohjelmassa opastan sinua luomaan yhteyden GitLabin ja Pantheonin välille ja optimoimaan WordPress- ja Drupal-työnkulkusi.

On tietysti mahdollista, peili GitLab-arkisto, mutta teemme kaiken käsillämme syventyäksemme GitLab CI ja käytä tätä työkalua tulevaisuudessa paitsi käyttöönottoon.

Esittely

Tätä viestiä varten sinun on ymmärrettävä, että Pantheon jakaa jokaisen sivuston kolmeen osaan: koodi, tietokanta ja tiedostot.

Koodi sisältää CMS-tiedostoja, kuten WordPress-ytimen, laajennuksia ja teemoja. Näitä tiedostoja hallitaan sisään Git arkistot, jota isännöi Pantheon, mikä tarkoittaa, että voimme ottaa käyttöön koodin GitLabista Pantheoniin Gitin avulla.
Pantheonin tiedostot ovat mediatiedostoja, eli kuvia sivustolle. Tyypillisesti käyttäjät lataavat ne, ja Git jättää ne huomiotta.

Luo ilmainen tili, lue lisää Pantheonin työnkulku tai rekisteröidy demoon osoitteessa pantheon.io.

oletukset

Projektini Pantheonissa ja GitLabissa on ns pantheon-gitlab-blog-demo. Projektin nimen on oltava yksilöllinen. Täällä työskentelemme WordPress-sivuston kanssa. Voit ottaa Drupalin, mutta sinun on muutettava joitain asioita.

Aion käyttää Git komentorivija voit työskennellä graafinen käyttöliittymä, jos haluat.

Luo projekti

Ensin luodaan GitLab-projekti (palaamme tähän myöhemmin).

Nyt WordPress-sivuston luominen Pantheoniin. Sitten asennamme WordPressin sivuston kojelautaan.

Jos kätesi kutinaa muuttaa jotain, esimerkiksi poistaa tai lisätä laajennuksia, ole kärsivällinen. Sivustoa ei ole vielä yhdistetty GitLabiin, ja haluamme kaikkien koodimuutosten menevän GitLabin kautta.

Kun olemme asentaneet WordPressin, palaa Pantheon-verkkosivuston hallintapaneeliin ja vaihda kehitystilaksi Git.

GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi

Ensimmäinen sitoumus GitLabissa

Nyt sinun on siirrettävä alkuperäinen WordPress-koodi Pantheon-sivustolta GitLabiin. Tätä varten kloonaamme koodin Pantheon-sivuston Git-arkistosta paikallisesti ja lähetämme sen sitten GitLab-arkistoon.

Jotta se olisi helpompaa ja turvallisempaa, Lisää SSH-avain Pantheoniin ja meidän ei tarvitse syöttää salasanaa joka kerta, kun kloonaamme Pantheon Git -arkiston. Samaan aikaan jo lisää SSH-avain GitLabiin.

Voit tehdä tämän kloonaamalla Pantheon-verkkosivuston paikallisesti kopioimalla komento verkkosivuston kojelaudan Kloonaa Gitillä -kentästä.

GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi
Jos tarvitset apua, lue dokumentaatio Git for Pantheonin käytön aloittaminen.

Nyt muutetaan git remote originosoittaa GitLabia Pantheonin sijaan. Se voi olla tehty командой git remote.

Siirrytään GitLab-projektiin ja kopioidaan arkiston URL-osoite projektin tietosivun Klooni-pudotusvalikosta. Valitaan Kloonaa SSH:lla -vaihtoehto, koska olemme jo määrittäneet SSH-avaimen.

GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi

Oletuksena git remote koodivaraston paikalliselle kopiolle - origin. Tätä voidaan muuttaa c git remote set-url origin [URL репозитория GitLab], jossa hakasulkeiden sijaan kirjoitamme todellisen URL-osoitteen.

Lopuksi käynnistetään git push origin master --forcetyöntämään WordPress-koodia Pantheonista GitLabiin.

-Force-vaihtoehtoa tarvitaan vain kerran. Sitten joukkueissa git push se ei tule olemaan GitLabissa.

Tunnistetietojen ja muuttujien määrittäminen

Muistatko kuinka lisäsimme SSH-avaimen paikallisesti kirjautumaan Pantheoniin ja GitLabiin? SSH-tunnusta voidaan käyttää valtuuttamaan GitLab ja Pantheon.

GitLabilla on erinomainen dokumentaatio. Katsotaan osio SSH-avaimista käytettäessä Docker-suoritinta asiakirjassa SSH-avaimien käytöstä GitLab CI/CD:n kanssa.

Suoritamme nyt kaksi ensimmäistä vaihetta: Luodaan uusi SSH-avainpari paikallisesti ssh-keygenillä ja lisätään yksityinen avain muuttujaksi projektiin.

Sitten kysytään SSH_PRIVATE_KEY как GitLab CI/CD -ympäristömuuttuja projektin asetuksissa.
Kolmannessa ja neljännessä vaiheessa luomme tiedoston .gitlab-ci.yml tällaisella sisällöllä:

before_script:
  # See https://docs.gitlab.com/ee/ci/ssh_keys/README.html
  - eval $(ssh-agent -s)
  - echo "$SSH_PRIVATE_KEY" | tr -d 'r' | ssh-add - > /dev/null
  - mkdir -p $HOME/.ssh && echo "StrictHostKeyChecking no" >> "$HOME/.ssh/config"
  - git config --global user.email "$GITLAB_USER_EMAIL"
  - git config --global user.name "Gitlab CI"

Älkäämme sitoko tiedostoa vielä .gitlab-ci.yml, sinun on lisättävä siihen jotain muuta.

Nyt suoritamme viidennen vaiheen ja lisää ensimmäisessä vaiheessa luomasi julkinen avain palveluihin, joihin tarvitset pääsyn rakennusympäristössä.

Meidän tapauksessamme haluamme päästä Pantheoniin GitLabista. Noudatamme Pantheon-asiakirjan ohjeita SSH-avaimen lisääminen Pantheoniin ja suorita tämä vaihe.

Muista: yksityinen SSH on GitLabissa, avoin SSH on Pantheonissa.

Asetetaan vielä muutama ympäristömuuttuja. Ensimmäinen on nimeltään PANTHEON_SITE. Sen arvo on koneessasi olevan Pantheon-sivuston nimi.

Koneen nimi on lueteltu Clone with Git -komennon lopussa. Olet jo kloonannut sivuston paikallisesti, joten tämä on paikallisen arkistohakemiston nimi.

GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi

Seuraavaksi asetetaan ympäristömuuttuja PANTHEON_GIT_URL. Tämä on Git-varaston URL-osoite Pantheon-sivustolle, jota olemme jo käyttäneet.

Anna vain SSH-arkiston URL-osoite ilman git clone ja koneen lopussa olevan sivuston nimi.

Huh huh. Se on tehty, nyt voimme viimeistellä tiedostomme .gitlab-ci.yml.

Luo käyttöönottotehtävä

Se, mitä alun perin teemme GitLab CI:n kanssa, on hyvin samanlaista kuin mitä olemme tehneet Git-varastojen kanssa aiemmin. Mutta tällä kertaa lisätään Pantheon-arkisto toiseksi Git-etälähteeksi ja työnnetään sitten koodi GitLabista Pantheoniin.

Tehdään tämä määrittämällä vaihe deploy и tehtävä deploy:dev, koska otamme käyttöön Pantheonin kehitysympäristön. Tuloksena oleva tiedosto .gitlab-ci.yml Se näyttää tältä:

stages:
- deploy

before_script:
  # See https://docs.gitlab.com/ee/ci/ssh_keys/README.html
  - eval $(ssh-agent -s)
  - echo "$SSH_PRIVATE_KEY" | tr -d 'r' | ssh-add - > /dev/null
  - mkdir -p $HOME/.ssh && echo "StrictHostKeyChecking no" >> "$HOME/.ssh/config"
  - git config --global user.email "$GITLAB_USER_EMAIL"
  - git config --global user.name "Gitlab CI"

deploy:dev:
  stage: deploy
  environment:
    name: dev
    url: https://dev-$PANTHEON_SITE.pantheonsite.io/
  script:
    - git remote add pantheon $PANTHEON_GIT_URL
    - git push pantheon master --force
  only:
    - master

muuttujat SSH_PRIVATE_KEY, PANTHEON_SITE и PANTHEON_GIT_URL pitäisi näyttää tutulta - määritimme nämä ympäristömuuttujat aiemmin. Näillä muuttujilla voimme käyttää tiedoston arvoja .gitlab-ci.yml monta kertaa, ja ne tarvitsee päivittää vain yhteen paikkaan.

Lopuksi lisää, sitoudu ja lähetä tiedosto .gitlab-ci.yml GitLabissa.

Tarkistetaan käyttöönottoa

Jos teimme kaiken oikein, tehtävä deploy:dev toimii onnistuneesti GitLab CI/CD:ssä ja lähetä sitoumus .gitlab-ci.yml Pantheonissa. Katsotaanpa.

GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi

GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi

GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi

Lähetetään yhdistämispyyntösäikeitä Pantheoniin

Tässä käytämme suosikki Pantheon-ominaisuuttani − multidev, jossa voit luoda lisää Pantheon-ympäristöjä Git-haaroihin pyynnöstä.

Pääsy multideviin on rajoitettu, joten tämä osio voidaan ohittaa. Mutta jos sinulla on käyttöoikeus, voit lisätä tuottavuutta vakavasti määrittämällä automaattisten monitoimiympäristöjen luomisen Pantheoniin GitLabin yhdistämispyynnöistä.

Tehdään ensin uusi Git-haara paikallisesti käyttämällä git checkout -b multidev-support. Muutetaan nyt taas jotain .gitlab-ci.yml.

Haluan sisällyttää yhdistämispyynnön numeron Pantheon-ympäristön nimeen. Esimerkiksi ensimmäinen yhdistämispyyntö on mr-1, toinen - mr-2 jne.

Yhdistämispyyntö muuttuu, joten meidän on määritettävä Pantheon-haarojen nimet dynaamisesti. Se on helppoa GitLabissa - sinun tarvitsee vain käyttää ennalta määritellyt ympäristömuuttujat.

Voimme ottaa $CI_MERGE_REQUEST_IIDmäärittääksesi yhdistämispyynnön numeron. Otetaan tämä kaikki käyttöön aiemmin määrittämiemme globaalien ympäristömuuttujien kanssa ja lisätään uusi deploy:multidev-tehtävä tiedoston loppuun .gitlab-ci.yml.

deploy:multidev:
  stage: deploy
  environment:
    name: multidev/mr-$CI_MERGE_REQUEST_IID
    url: https://mr-$CI_MERGE_REQUEST_IID-$PANTHEON_SITE.pantheonsite.io/
  script:
    # Checkout the merge request source branch
    - git checkout $CI_COMMIT_REF_NAME
    # Add the Pantheon git repository as an additional remote
    - git remote add pantheon $PANTHEON_GIT_URL
    # Push the merge request source branch to Pantheon
    - git push pantheon $CI_COMMIT_REF_NAME:mr-$CI_MERGE_REQUEST_IID --force
  only:
    - merge_requests

Se tulee olemaan samanlainen kuin meidän tehtävämme deploy:dev, vain haara lähetetään Pantheoniin, ei master.

Olemme lisänneet ja sitoneet päivitetyn tiedoston .gitlab-ci.yml, ja nyt työnnetään uusi haara GitLabille git push -u origin multidev-support.

Luodaan nyt haaralta uusi yhdistämispyyntö multidev-supportklikkaamalla Luo yhdistämispyyntö.

GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi

Kun yhdistämispyynnön on luotu, katsomme, kuinka CI/CD-tehtävä suoritetaan deploy:multidev.

GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi

Katsokaa, uusi viestiketju on lähetetty Pantheoniin. Mutta jos siirrymme Pantheon-sivuston kojelaudan multidev-osioon, emme näe uutta ympäristöä siellä

GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi

Katsotaanpa Git Branches -osiota.

GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi

Tämän seurauksena lankamme mr-1 pääsi Pantheoniin. Luodaan ympäristö haarasta mr-1.

GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi

Olemme luoneet multidev-ympäristön, nyt palataan GitLabiin ja katsotaan osiota Toiminnot > Ympäristöt. Näemme merkinnät dev и mr-1.

Tämä johtuu siitä, että lisäsimme merkinnän environment Nimellä name и url CI/CD-tehtäviin. Jos napsautamme avoimen ympäristön kuvaketta, siirrymme Pantheonin multidev-ympäristön URL-osoitteeseen.

Automatisoi multidevin luominen

Periaatteessa voit lopettaa tähän ja muistaa luoda multidev-ympäristön jokaiselle yhdistämispyynnölle, mutta tämä prosessi voidaan automatisoida.

Pantheonissa on komentorivityökalu Pääteasema, jossa voit työskennellä alustan kanssa automaattisesti. Terminuksen avulla voit luoda multidev-ympäristöjä komentoriviltä - ihanteellinen GitLab CI.

Tarvitsemme uuden yhdistämispyynnön tämän testaamiseksi. Luodaan uusi haara käyttämällä git checkout -b auto-multidev-creation.

Terminuksen käyttäminen GitLab CI/CD -tehtävissä tarvitset konetunnuksen Terminuksen todentamista varten ja konttikuvan Terminuksen kanssa.

Pantheon-konetunnuksen luominen, tallenna se turvalliseen paikkaan ja lisää se globaaliksi ympäristömuuttujaksi GitLabissa nimellä PANTHEON_MACHINE_TOKEN.

Jos unohdit lisätä GitLab-ympäristömuuttujia, palaa määrittämäämme kohtaan PANTHEON_SITE.

Docker-tiedoston luominen Terminuksen avulla

Jos et käytä Dockeria tai et pidä tiedostoista Dockerfile, ota kuvani registry.gitlab.com/ataylorme/pantheon-gitlab-blog-demo:latest ja ohita tämä osio.

GitLabilla on konttirekisteri, jossa voimme rakentaa ja sijoittaa Docker-tiedoston projektiamme varten. Luodaan Docker-tiedosto Terminuksen kanssa työskentelemään Pantheonin kanssa.

Terminus on PHP-komentorivityökalu, joten aloitetaan PHP-kuvasta. Asensen Terminuksen Composerin kautta, joten käytän virallinen Docker Composer -kuva. Me luomme Dockerfile paikallisessa arkistohakemistossa seuraavalla sisällöllä:

# Use the official Composer image as a parent image
FROM composer:1.8

# Update/upgrade apk
RUN apk update
RUN apk upgrade

# Make the Terminus directory
RUN mkdir -p /usr/local/share/terminus

# Install Terminus 2.x with Composer
RUN /usr/bin/env COMPOSER_BIN_DIR=/usr/local/bin composer -n --working-dir=/usr/local/share/terminus require pantheon-systems/terminus:"^2"

Noudata osiosta annettuja ohjeita kuvien kokoamiseen ja lähettämiseen Rakenna ja työnnä kuvia в kontin rekisteriasiakirjatkerätäksesi kuvan Dockerfile ja työnnä se GitLabiin.

Osaston avaaminen rekisterin GitLab-projektissa. Jos kaikki meni suunnitelmien mukaan, kuvamme on siellä. Kirjoita muistiin linkki kuvatunnisteeseen - tarvitsemme sen tiedostoa varten .gitlab-ci.yml.

GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi

jakso script ongelmassa deploy:multidev alkaa kasvaa, joten siirretään se erilliseen tiedostoon. Luo uusi tiedosto private/multidev-deploy.sh:

#!/bin/bash

# Store the mr- environment name
export PANTHEON_ENV=mr-$CI_MERGE_REQUEST_IID

# Authenticate with Terminus
terminus auth:login --machine-token=$PANTHEON_MACHINE_TOKEN

# Checkout the merge request source branch
git checkout $CI_COMMIT_REF_NAME

# Add the Pantheon Git repository as an additional remote
git remote add pantheon $PANTHEON_GIT_URL

# Push the merge request source branch to Pantheon
git push pantheon $CI_COMMIT_REF_NAME:$PANTHEON_ENV --force

# Create a function for determining if a multidev exists
TERMINUS_DOES_MULTIDEV_EXIST()
{
    # Stash a list of Pantheon multidev environments
    PANTHEON_MULTIDEV_LIST="$(terminus multidev:list ${PANTHEON_SITE} --format=list --field=id)"

    while read -r multiDev; do
        if [[ "${multiDev}" == "$1" ]]
        then
            return 0;
        fi
    done <<< "$PANTHEON_MULTIDEV_LIST"

    return 1;
}

# If the mutltidev doesn't exist
if ! TERMINUS_DOES_MULTIDEV_EXIST $PANTHEON_ENV
then
    # Create it with Terminus
    echo "No multidev for $PANTHEON_ENV found, creating one..."
    terminus multidev:create $PANTHEON_SITE.dev $PANTHEON_ENV
else
    echo "The multidev $PANTHEON_ENV already exists, skipping creating it..."
fi

Käsikirjoitus on yksityisessä hakemistossa ja ei salli Internetin käyttöä Pantheoniin. Meillä on käsikirjoitus multidev-logiikallemme. Päivitetään nyt osio deploy:multidev tiedosto .gitlab-ci.ymlniin että siitä tulee näin:

deploy:multidev:
  stage: deploy
  environment:
    name: multidev/mr-$CI_MERGE_REQUEST_IID
    url: https://mr-$CI_MERGE_REQUEST_IID-$PANTHEON_SITE.pantheonsite.io/
  script:
    # Run the multidev deploy script
    - "/bin/bash ./private/multidev-deploy.sh"
  only:
    - merge_requests

Meidän on varmistettava, että tehtävämme suoritetaan luodussa mukautetussa kuvassa, joten lisätään määritelmä image rekisterin URL-osoitteesta osoitteeseen .gitlab-ci.yml. Tämän seurauksena päädyimme tällaiseen tiedostoon .gitlab-ci.yml:

image: registry.gitlab.com/ataylorme/pantheon-gitlab-blog-demo:latest

stages:
- deploy

before_script:
  # See https://docs.gitlab.com/ee/ci/ssh_keys/README.html
  - eval $(ssh-agent -s)
  - echo "$SSH_PRIVATE_KEY" | tr -d 'r' | ssh-add - > /dev/null
  - mkdir -p $HOME/.ssh && echo "StrictHostKeyChecking no" >> "$HOME/.ssh/config"
  - git config --global user.email "$GITLAB_USER_EMAIL"
  - git config --global user.name "Gitlab CI"

deploy:dev:
  stage: deploy
  environment:
    name: dev
    url: https://dev-$PANTHEON_SITE.pantheonsite.io/
  script:
    - git remote add pantheon $PANTHEON_GIT_URL
    - git push pantheon master --force
  only:
    - master

deploy:multidev:
  stage: deploy
  environment:
    name: multidev/mr-$CI_MERGE_REQUEST_IID
    url: https://mr-$CI_MERGE_REQUEST_IID-$PANTHEON_SITE.pantheonsite.io/
  script:
    # Run the multidev deploy script
    - "/bin/bash ./private/multidev-deploy.sh"
  only:
    - merge_requests

Lisää, sitoudu ja lähetä private/multidev-deploy.sh и .gitlab-ci.yml. Nyt palaamme GitLabiin ja odotamme CI/CD-tehtävän valmistumista. Ole kärsivällinen: Multidevin luominen voi kestää useita minuutteja.

Sitten katsomme Pantheonin multidev-luetteloa. Voi ihme! Multidev-ympäristö mr-2 jo täällä.

GitLabin ja Pantheonin yhdistäminen ja Drupal- ja WordPress-työnkulkujen optimointi

Johtopäätös

Tiimilläni oli paljon hauskempaa, kun aloimme avata yhdistämispyyntöjä ja luoda ympäristöjä automaattisesti.

GitLabin ja Pantheonin tehokkailla työkaluilla voit yhdistää GitLabin Pantheoniin automaattisesti.

Koska käytämme GitLab CI/CD:tä, työnkulullamme on tilaa kasvaa. Tässä on pari ideaa, joilla pääset alkuun:

Kerro mielipiteesi GitLabista, Pantheonista ja automaatiosta.

PS Tiesitkö, että Terminus, Pantheonin komentorivityökalu, voidaan laajentaa liitännäisillä?

Me Pantheonissa olemme tehneet hyvää työtä version 2 parissa laajennus Terminus build -työkaluille GitLab-tuella. Jos et halua vaivautua jokaisen projektin asetuksiin, kokeile tätä laajennusta ja auta meitä testaamaan v2-beta. Terminuksen tiimille build:project:create Tarvitset vain Pantheon-tunnuksen ja GitLab-tunnuksen. Hän ottaa käyttöön yhden Composerin ja automaattisen testauksen esimerkkiprojekteista, luo GitLabissa uuden projektin, uuden Pantheon-sivuston, ja yhdistää ne ympäristömuuttujien ja SSH-avaimien avulla.

Tietoja kirjoittajasta

Andrew Taylor luo työkaluja kehittäjille Pantheon.

Lähde: will.com

Lisää kommentti