Opcje potoku dla repozytoriów Git

Azure DevOps Services | Azure DevOps Server 2022 — Azure DevOps Server 2019

Podczas edytowania potoku korzystającego z repozytorium Git — w projekcie Usługi Azure DevOps, GitHub, GitHub Enterprise Server, Bitbucket Cloud lub innym repozytorium Git — dostępne są następujące opcje.

Funkcja Azure Pipelines Azure DevOps Server 2019 i nowsze wersje TFS 2018
Oddział Tak Tak Tak
Oczyszczanie Tak Tak Tak
Źródła tagów lub etykiet Projektu; Tylko wersja klasyczna Projekt zespołowy Projekt zespołowy
Stan kompilacji raportu Tak Tak Tak
Zapoznaj się z podmodułami Tak Tak Tak
Wyewidencjonowywanie plików z LFS Tak Tak Tak
Klonowanie drugiego repozytorium Tak Tak Tak
Nie synchronizuj źródeł Tak Tak Tak
Płytkie pobieranie Tak Tak Tak

Uwaga

Kliknij pozycję Ustawienia zaawansowane w zadaniu Pobierz źródła , aby wyświetlić niektóre z powyższych opcji.

Oddział

Jest to gałąź, która ma być domyślna podczas ręcznego kolejkowania tej kompilacji. Jeśli ustawisz zaplanowany wyzwalacz kompilacji, jest to gałąź, z której kompilacja uzyska najnowsze źródła. Gałąź domyślna nie ma łożyska, gdy kompilacja jest wyzwalana za pośrednictwem ciągłej integracji. Zazwyczaj ustawisz tę wartość tak samo jak domyślna gałąź repozytorium (na przykład "master").

Czyszczenie repozytorium lokalnego na agencie

Przed uruchomieniem kompilacji można wykonać różne formy czyszczenia katalogu roboczego własnego agenta.

Ogólnie rzecz biorąc, aby zapewnić szybszą wydajność własnych agentów, nie usuwaj repozytorium. W tym przypadku, aby uzyskać najlepszą wydajność, upewnij się, że kompilujesz również przyrostowo, wyłączając dowolną opcję Wyczyść zadania lub narzędzia używanego do kompilowania.

Jeśli musisz wyczyścić repozytorium (na przykład uniknąć problemów spowodowanych przez pliki reszt z poprzedniej kompilacji), dostępne są poniższe opcje.

Uwaga

Czyszczenie nie jest skuteczne, jeśli używasz agenta hostowanego przez firmę Microsoft, ponieważ za każdym razem otrzymasz nowego agenta. W przypadku korzystania z własnych agentów w zależności od konfiguracji pul agentów można uzyskać nowego agenta dla kolejnych przebiegów potoku (lub etapów lub zadań w tym samym potoku), więc nie jest to gwarancja, że kolejne uruchomienia, zadania lub etapy będą mogły uzyskiwać dostęp do danych wyjściowych z poprzednich przebiegów, zadań lub etapów.

Uwaga

W przypadku korzystania z własnych agentów w zależności od konfiguracji pul agentów można uzyskać nowego agenta dla kolejnych przebiegów potoku (lub etapów lub zadań w tym samym potoku), więc nie jest to gwarancja, że kolejne uruchomienia, zadania lub etapy będą mogły uzyskiwać dostęp do danych wyjściowych z poprzednich przebiegów, zadań lub etapów. Artefakty kompilacji umożliwiają udostępnianie danych wyjściowych przebiegu, etapu lub zadania potoku kolejnym przebiegom, etapom lub zadaniu.

Azure Pipelines, Azure DevOps Server 2019 i nowsze

Istnieje kilka różnych opcji czyszczenia dostępnych dla potoków YAML.

  • Krok checkout ma clean opcję. Po ustawieniu truewartości na wartość potok jest uruchamiany execute git clean -ffdx && git reset --hard HEAD przed pobraniem repozytorium. Aby uzyskać więcej informacji, zobacz Wyewidencjonuj.
  • Ustawienie dla workspacejob opcji ma wiele czystych opcji (dane wyjściowe, zasoby, wszystkie). Aby uzyskać więcej informacji, zobacz Obszar roboczy.
  • Interfejs użytkownika ustawień potoku ma ustawienie Czyste , które w przypadku ustawienia wartości true jest równoważne określeniu clean: true dla każdego checkout kroku w potoku. Aby skonfigurować ustawienie Czyszczenie :
    1. Edytuj potok, wybierz pozycję ..., a następnie wybierz pozycję Wyzwalacze.

      Edytuj wyzwalacze.

    2. Wybierz pozycję YAML, Pobierz źródła i skonfiguruj odpowiednie ustawienie Wyczyść . Wartość domyślna to true.

      Wyczyść ustawienie.

Aby zastąpić ustawienia czyszczenia podczas ręcznego uruchamiania potoku, możesz użyć parametrów środowiska uruchomieniowego. W poniższym przykładzie parametr środowiska uruchomieniowego służy do konfigurowania ustawienia czyszczenia wyewidencjonowania.

parameters:
- name: clean
  displayName: Checkout clean
  type: boolean
  default: true
  values:
  - false
  - true

trigger:
- main

pool: FabrikamPool
#  vmImage: 'ubuntu-latest'

steps:
- checkout: self
  clean: ${{ parameters.clean }}

Domyślnie clean jest ustawiona wartość true , ale można ją przesłonić podczas ręcznego uruchamiania potoku, usuwając zaznaczenie pola wyboru Wyczyść wyewidencjonowanie dodane dla parametru środowiska uruchomieniowego.

Źródła etykiet

Możesz oznaczyć etykiety plikami kodu źródłowego, aby umożliwić zespołowi łatwe zidentyfikowanie wersji każdego pliku zawartego w ukończonej kompilacji. Istnieje również możliwość określenia, czy kod źródłowy powinien być oznaczony etykietą dla wszystkich kompilacji, czy tylko w przypadku pomyślnych kompilacji.

Uwaga

Tej funkcji można używać tylko wtedy, gdy repozytorium źródłowe w kompilacji jest repozytorium GitHub lub repozytorium Git lub TFVC z projektu.

W formacie Etykieta można użyć zmiennych zdefiniowanych przez użytkownika i wstępnie zdefiniowanych, które mają zakres "Wszystkie". Na przykład:

$(Build.DefinitionName)_$(Build.DefinitionVersion)_$(Build.BuildId)_$(Build.BuildNumber)_$(My.Variable)

Pierwsze cztery zmienne są wstępnie zdefiniowane. My.Variable Można go zdefiniować na karcie zmiennych.

Potok kompilacji etykietuje źródła za pomocą tagu Git.

Niektóre zmienne kompilacji mogą zwracać wartość, która nie jest prawidłową etykietą. Na przykład zmienne, takie jak $(Build.RequestedFor) i $(Build.DefinitionName) mogą zawierać białe znaki. Jeśli wartość zawiera biały znak, tag nie zostanie utworzony.

Po otagowaniu źródeł przez potok kompilacji artefakt z ref usługi Git refs/tags/{tag} zostanie automatycznie dodany do ukończonej kompilacji. Zapewnia to zespołowi dodatkową możliwość śledzenia i bardziej przyjazny dla użytkownika sposób przechodzenia z kompilacji do utworzonego kodu. Tag jest uważany za artefakt kompilacji, ponieważ jest generowany przez kompilację. Jeśli kompilacja zostanie usunięta ręcznie lub za pomocą zasad przechowywania, tag zostanie również usunięty.

Stan kompilacji raportu (Azure Pipelines, TFS 2018 i nowsze)

Masz możliwość nadania zespołowi widoku stanu kompilacji z repozytorium zdalnego źródła.

Jeśli źródła znajdują się w repozytorium Git usługi Azure Repos w projekcie, ta opcja wyświetla wskaźnik na stronie Kod , aby wskazać, czy kompilacja przechodzi, czy kończy się niepowodzeniem. Stan kompilacji jest wyświetlany na następujących kartach:

  • Pliki: wskazuje stan najnowszej kompilacji dla wybranej gałęzi.
  • Zatwierdzenia: wskazuje stan kompilacji każdego zatwierdzenia (wymaga to włączenia wyzwalacza ciągłej integracji dla kompilacji).
  • Gałęzie: wskazuje stan najnowszej kompilacji dla każdej gałęzi.

Jeśli używasz wielu potoków kompilacji dla tego samego repozytorium w projekcie, możesz włączyć tę opcję dla co najmniej jednego potoku. W przypadku włączenia tej opcji w wielu potokach wskaźnik na stronie Kod wskazuje stan najnowszej kompilacji we wszystkich potokach. Członkowie zespołu mogą kliknąć wskaźnik stanu kompilacji, aby wyświetlić najnowszy stan kompilacji dla każdego z potoków kompilacji.

GitHub

Jeśli źródła znajdują się w usłudze GitHub, ta opcja publikuje stan kompilacji w usłudze GitHub przy użyciu interfejsów API sprawdzania lub stanu usługi GitHub. Jeśli kompilacja zostanie wyzwolona z żądania ściągnięcia w usłudze GitHub, możesz wyświetlić stan na stronie Żądań ściągnięcia w usłudze GitHub. Umożliwia to również ustawianie zasad stanu w usłudze GitHub i automatyzowanie scalania. Jeśli kompilacja jest wyzwalana przez ciągłą integrację, możesz wyświetlić stan kompilacji w zatwierdzeniu lub gałęzi w usłudze GitHub.

Inne typy repozytoriów zdalnych Git

Jeśli źródło znajduje się w innym typie repozytorium zdalnego, nie można użyć usługi Azure Pipelines ani serwera TFS, aby automatycznie opublikować stan kompilacji w tym repozytorium. Można jednak użyć wskaźnika kompilacji jako sposobu integrowania i pokazywania stanu kompilacji w środowiskach kontroli wersji.

Ścieżka wyewidencjonowania

Jeśli domyślnie wyewidencjonujesz pojedyncze repozytorium, kod źródłowy zostanie wyewidencjonowany w katalogu o nazwie s. W przypadku potoków YAML można to zmienić, określając element za pomocą checkout elementu path. Określona ścieżka jest względna do $(Agent.BuildDirectory). Na przykład: jeśli wartość ścieżki wyewidencjonowania to mycustompath i $(Agent.BuildDirectory) ma C:\agent\_work\1wartość , kod źródłowy zostanie wyewidencjonowany w pliku C:\agent\_work\1\mycustompath.

Jeśli używasz wielu checkout kroków i wyewidencjonujesz wiele repozytoriów, a nie jawnie określasz folderu przy użyciu polecenia path, każde repozytorium zostanie umieszczone w podfolderze nazwanym s po repozytorium. Jeśli na przykład wyewidencjonujesz dwa repozytoria o nazwie tools i code, kod źródłowy zostanie wyewidencjonowany w C:\agent\_work\1\s\tools systemach i C:\agent\_work\1\s\code.

Należy pamiętać, że nie można ustawić wartości ścieżki wyewidencjonowania, aby przejść w górę poziomów katalogów powyżej $(Agent.BuildDirectory), więc path\..\anotherpath spowoduje to prawidłową ścieżkę wyewidencjonowania (tj. C:\agent\_work\1\anotherpath), ale wartość taka jak ..\invalidpath nie (tj. C:\agent\_work\invalidpath).

Jeśli używasz wielu checkout kroków i wyewidencjonujesz wiele repozytoriów i chcesz jawnie określić folder przy użyciu metody path, rozważ uniknięcie ustawienia ścieżki, która jest podfolderem innego kroku wyewidencjonowania (tj. C:\agent\_work\1\s\repo1 i C:\agent\_work\1\s\repo1\repo2), w przeciwnym razie podfolder kroku wyewidencjonowania zostanie wyczyszczone przez czyszczenie innego repozytorium. Należy pamiętać, że ten przypadek jest prawidłowy, jeśli opcja clean ma wartość true dla repo1elementu )

Uwaga

Ścieżkę wyewidencjonowania można określić tylko dla potoków YAML. Aby uzyskać więcej informacji, zobacz Wyewidencjonuj w schemacie YAML.

Wyewidencjonowywanie modułów podrzędnych

Wybierz, jeśli chcesz pobrać pliki z modułów podrzędnych. Możesz wybrać opcję pobrania natychmiastowych modułów podrzędnych lub wszystkich modułów podrzędnych zagnieżdżonych do dowolnej głębokości rekursji. Jeśli chcesz użyć funkcji LFS z modułami podrzędnymi, pamiętaj, aby zapoznać się z uwagami dotyczącymi używania funkcji LFS z modułami podrzędnymi.

Uwaga

Aby uzyskać więcej informacji na temat składni YAML na potrzeby wyewidencjonowania modułów podrzędnych, zobacz Wyewidencjonowywanie w schemacie YAML.

Potok kompilacji wyewidencjonuje podmoduły usługi Git, o ile są:

  • Nieuwierzytelnione: publiczne, nieuwierzytelnione repozytorium bez poświadczeń wymaganych do klonowania lub pobierania.

  • Uwierzytelniony:

    • Zawarte w tym samym projekcie, organizacji usługi GitHub lub koncie usługi Bitbucket Cloud co repozytorium Git określone powyżej.

    • Dodano przy użyciu adresu URL względem repozytorium głównego. Na przykład ten zostanie wyewidencjonowany: git submodule add /../../submodule.git mymodule ten nie zostanie wyewidencjonowany: git submodule add https://dev.azure.com/fabrikamfiber/_git/ConsoleApp mymodule

Uwierzytelnione moduły podrzędne

Uwaga

Upewnij się, że moduły podrzędne zostały zarejestrowane przy użyciu protokołu HTTPS i nie korzystają z protokołu SSH.

Te same poświadczenia, które są używane przez agenta do pobierania źródeł z repozytorium głównego, są również używane do pobierania źródeł dla modułów podrzędnych.

Jeśli repozytorium główne i moduły podrzędne znajdują się w repozytorium Git usługi Azure Repos w projekcie usługi Azure DevOps, możesz wybrać konto używane do uzyskiwania dostępu do źródeł. Na karcie Opcje w menu Zakres autoryzacji zadania kompilacji wybierz jedną z następujących opcji:

  • Kolekcja projektów do korzystania z konta usługi Project Collection Build

  • Bieżący projekt do korzystania z konta usługi Project Build Service.

Upewnij się, że w zależności od używanego konta masz dostęp zarówno do repozytorium głównego, jak i do modułów podrzędnych.

Jeśli repozytorium główne i moduły podrzędne znajdują się w tej samej organizacji usługi GitHub, token przechowywany w połączeniu usługi GitHub jest używany do uzyskiwania dostępu do źródeł.

Alternatywa dla opcji wyewidencjonowania modułów podrzędnych

W niektórych przypadkach nie można użyć opcji Wyewidencjonuj moduły podrzędne . Może istnieć scenariusz, w którym potrzebny jest inny zestaw poświadczeń w celu uzyskania dostępu do modułów podrzędnych. Może się to zdarzyć, na przykład jeśli repozytorium główne i repozytoria podrzędne nie są przechowywane w tej samej organizacji lub usłudze Git usługi Azure DevOps.

Jeśli nie możesz użyć opcji Wyewidencjonuj moduły podrzędne , możesz zamiast tego użyć niestandardowego kroku skryptu, aby pobrać moduły podrzędne. Najpierw uzyskaj osobisty token dostępu (PAT) i prefiks za pomocą pat:polecenia . Następnie zakoduj ten prefiksowy ciąg base64, aby utworzyć podstawowy token uwierzytelniania. Na koniec dodaj ten skrypt do potoku:

git -c http.https://<url of submodule repository>.extraheader="AUTHORIZATION: basic <BASE64_ENCODED_TOKEN_DESCRIBED_ABOVE>" submodule update --init --recursive

Pamiętaj, aby zastąpić ciąg "<BASIC_AUTH_TOKEN>" tokenem zakodowanym w formacie Base64.

Użyj zmiennej tajnej w projekcie lub potoku kompilacji, aby przechowywać wygenerowany podstawowy token uwierzytelniania. Użyj tej zmiennej, aby wypełnić wpis tajny w powyższym poleceniu git.

Uwaga

Pyt.: Dlaczego nie mogę użyć menedżera poświadczeń Git w agencie?Uwierzytelnianie: Przechowywanie poświadczeń modułu podrzędnego w menedżerze poświadczeń usługi Git zainstalowanym na prywatnym agencie kompilacji zwykle nie jest skuteczne, ponieważ menedżer poświadczeń może monitować o ponowne wprowadzenie poświadczeń po każdym zaktualizowaniu modułu podrzędnego. Nie jest to pożądane podczas automatycznych kompilacji, gdy interakcja użytkownika nie jest możliwa.

Wyewidencjonowywanie plików z LFS

Wybierz, jeśli chcesz pobrać pliki z dużego magazynu plików (LFS).

W edytorze klasycznym zaznacz pole wyboru, aby włączyć tę opcję.

W kompilacji YAML dodaj krok wyewidencjonowania z ustawioną wartością lfstrue:

steps:
- checkout: self
  lfs: true

Jeśli używasz serwera TFS lub jeśli używasz usługi Azure Pipelines z własnym agentem, musisz zainstalować git-lfs go na agencie, aby ta opcja działała. Jeśli hostowani agenci korzystają z systemu Windows, rozważ użycie zmiennej System.PreferGitFromPath , aby upewnić się, że potoki korzystają z wersji narzędzi git i git-lfs zainstalowanych na maszynie. Aby uzyskać więcej informacji, zobacz Jaka wersja usługi Git działa mój agent?

Używanie usługi Git LFS z modułami podrzędnymi

Jeśli moduł podrzędny zawiera pliki LFS, należy skonfigurować usługę Git LFS przed wyewidencjonowywaniem modułów podrzędnych. Agenci systemu macOS i Linux hostowani przez firmę Microsoft są wstępnie skonfigurowani w ten sposób. Agenci systemu Windows i agenci z systemem macOS/Linux mogą nie.

Aby obejść ten problem, jeśli używasz kodu YAML, możesz dodać następujący krok przed poleceniem checkout:

steps:
- script: |
    git config --global --add filter.lfs.required true
    git config --global --add filter.lfs.smudge "git-lfs smudge -- %%f"
    git config --global --add filter.lfs.process "git-lfs filter-process"
    git config --global --add filter.lfs.clean "git-lfs clean -- %%f"
  displayName: Configure LFS for use with submodules
- checkout: self
  lfs: true
  submodules: true
# ... rest of steps ...

Klonowanie drugiego repozytorium

Domyślnie potok jest skojarzony z jednym repozytorium z usługi Azure Repos lub dostawcą zewnętrznym. To jest repozytorium, które może wyzwalać kompilacje na zatwierdzeniach i żądaniach ściągnięcia.

Możesz uwzględnić źródła z drugiego repozytorium w potoku. Możesz to zrobić, pisząc skrypt.

git clone https://github.com/Microsoft/TypeScript.git

Jeśli repozytorium nie jest publiczne, musisz przekazać uwierzytelnianie do polecenia Git.

Azure Repos

Potok będzie miał już dostęp do innych repozytoriów w projekcie i można je sklonować w potoku przy użyciu polecenia skryptu, jak pokazano w poniższym przykładzie.

- script: | 
    git clone -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" https://organization@dev.azure.com/project/FabrikamFiber/_git/reponame

Możesz sklonować wiele repozytoriów w tym samym projekcie co potok przy użyciu wyewidencjonowania z wieloma repozytoriami.

Jeśli musisz sklonować repozytorium z innego projektu, który nie jest publiczny, musisz uwierzytelnić się jako użytkownik, który ma dostęp do tego projektu.

Uwaga

Użyj zmiennej tajnej, aby bezpiecznie przechowywać poświadczenia.

Zmienne tajne nie są automatycznie udostępniane skryptom jako zmiennych środowiskowych. Zobacz Zmienne tajne dotyczące sposobu mapowania ich w.

W przypadku usługi Azure Repos możesz użyć osobistego tokenu dostępu z uprawnieniem Kod (odczyt). Wyślij to jako pole hasła w nagłówku autoryzacji "Podstawowa" bez nazwy użytkownika. (Innymi słowy, base64-encode wartość :<PAT>, w tym dwukropek).

AUTH=$(echo -n ":$REPO_PAT" | openssl base64 | tr -d '\n')
git -c http.<repo URL>.extraheader="AUTHORIZATION: basic $AUTH" clone <repo URL> --no-checkout --branch master

Nie synchronizuj źródeł

Zadania niezwiązane z wdrażaniem automatycznie pobierają źródła. Użyj tej opcji, jeśli chcesz pominąć to zachowanie. Ta opcja może być przydatna w przypadkach, gdy chcesz:

  • Narzędzie Git init, konfiguracja i pobieranie przy użyciu własnych opcji niestandardowych.

  • Użyj potoku kompilacji, aby po prostu uruchomić automatyzację (na przykład niektóre skrypty), które nie zależą od kodu w kontroli wersji.

Jeśli chcesz wyłączyć pobieranie źródeł:

  • Azure Pipelines, TFS 2018 i nowsze: kliknij pozycję Ustawienia zaawansowane, a następnie wybierz pozycję Nie synchronizuj źródeł.

Uwaga

Jeśli używasz tej opcji, agent pomija również uruchamianie poleceń Git, które czyszczą repozytorium.

Płytkie pobieranie

Wybierz, jeśli chcesz ograniczyć, jak daleko w historii chcesz pobrać. Skutecznie powoduje to wyświetlenie polecenia git fetch --depth=n. Jeśli repozytorium jest duże, ta opcja może zwiększyć wydajność potoku kompilacji. Repozytorium może być duże, jeśli jest ono używane przez długi czas i ma możliwą do rozmiaru historię. Może to być również duże, jeśli dodano i później usunięto duże pliki.

W takich przypadkach ta opcja może pomóc w oszczędzaniu zasobów sieciowych i magazynowych. Może to również zaoszczędzić czas. Powodem, dla którego nie zawsze jest oszczędność czasu, jest to, że w niektórych sytuacjach serwer może potrzebować czasu na obliczanie zatwierdzeń do pobrania dla określonej głębokości.

Uwaga

Gdy kompilacja zostanie w kolejce, gałąź do kompilacji zostanie rozpoznana jako identyfikator zatwierdzenia. Następnie agent pobiera gałąź i sprawdza żądane zatwierdzenie. Istnieje małe okno między usunięciem gałęzi z identyfikatorem zatwierdzenia i wykonaniem wyewidencjonowania przez agenta. Jeśli gałąź zostanie zaktualizowana szybko i ustawisz bardzo małą wartość dla płytkiego pobierania, zatwierdzenie może nie istnieć, gdy agent spróbuje go wyewidencjonować. W takim przypadku zwiększ płytkie ustawienie głębokości pobierania.

Po zaznaczeniu pola wyboru, aby włączyć tę opcję, w polu Głębokość określ liczbę zatwierdzeń.

Napiwek

Zmienna wymieniona Agent.Source.Git.ShallowFetchDepth poniżej działa również i zastępuje kontrolki pola wyboru. W ten sposób można zmodyfikować ustawienie podczas kolejki kompilacji.

Preferuj usługę Git ze ścieżki

Domyślnie agent systemu Windows używa wersji narzędzia Git powiązanej z oprogramowaniem agenta. Firma Microsoft zaleca użycie wersji narzędzia Git powiązanej z agentem, ale istnieje kilka opcji zastąpienia tego domyślnego zachowania i użycia wersji usługi Git zainstalowanej na maszynie agenta w ścieżce.

Aby wyświetlić wersję usługi Git używaną przez potok, możesz zapoznać się z dziennikami checkout kroków w potoku, jak pokazano w poniższym przykładzie.

Syncing repository: PathFilter (Git)
Prepending Path environment variable with directory containing 'git.exe'.
git version
git version 2.26.2.windows.1

To ustawienie jest zawsze prawdziwe w przypadku agentów innych niż Windows.

Opcje wyzwalacza dla innego narzędzia Git

Po określeniu innego/zewnętrznego repozytorium Git kompilacje ciągłej integracji wymagają, aby repozytorium było dostępne z Internetu. Jeśli repozytorium znajduje się za zaporą lub serwerem proxy, tylko zaplanowane i ręczne kompilacje będą działać.

Często zadawane pytania

Jakie protokoły mogą być używane przez agenta kompilacji z usługą Git?

Agent obsługuje protokół HTTPS.

Agent nie obsługuje jeszcze protokołu SSH. Zobacz Zezwalaj kompilacji na używanie uwierzytelniania SSH podczas wyewidencjonowania modułów podrzędnych Git.

Używam lokalnego serwera TFS i nie widzę niektórych z tych funkcji. Dlaczego nie?

Niektóre z tych funkcji są dostępne tylko w usłudze Azure Pipelines i nie są jeszcze dostępne lokalnie. Niektóre funkcje są dostępne lokalnie, jeśli przeprowadzono uaktualnienie do najnowszej wersji serwera TFS.