Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- StringBuilder
- addDoc
- islowercase()
- 스프링
- while과 two-pointer
- 최대공약수와 최소공배수
- string과 stringbuilder
- 래퍼타입
- 스프링환경설정
- 자바 유클리드
- 동일성과 동등성
- isuppercase()
- 최소공배수
- sql 데이터형 변환
- 베주계수
- 모던자바
- Git사용법
- replaceAll()
- string
- toLowerCase()
- 스프링뼈대
- git 컨벤션
- 자바 스트링
- 유클리드호제법
- ineer join
- 최대공약수
- 자바 최소공배수
- 자바 최대공약수
- stringbuilder의 reverse()
- 프로그래머스 레벨1
Archives
- Today
- Total
주노 님의 블로그
20240927 본캠프 52일차 TIL 본문
오늘 해야할 일 ✔️ 🔺 ❌
🔺 JPA완강
🔺 DOKER 완강
JPA
더보기
영속성 전이
- 부모 엔티티 (OneTo~)에서 사용함
양쪽 엔티티의 라이프사이클이 동일해야함(게시글이 삭제되면, 첨부파일이 삭제되어야한다)
ALL : 전체 상태 전이
PERSIST : 저장 상태 전이
REMOVE : 삭제 상태 전이
MERGE : 업데이트 상태 전이
REFERESH : 갱신 상태 전이
DETACH : 비영속성 상태 전이
orphanRemoval(고아 객체 제거)
- 부모 엔티티 (OneTo~)에서 사용함
- Cascade.REMOVE와 비슷한 용도로 삭제를 전파하는데 쓰인다
부모 객체를 삭제하면 자식 객체는 매핑정보가 없어지므로, 대신 삭제해준다. - Cascade.REMOVE와 다른점 : Cascade.REMOVE는 일에 해당하는 부모 엔티티를 em.remove를 통해 직접 삭제할때 그 아래에 있는 다에 해당하는 자식 엔티티들이 삭제된다,
orphanRemoval=true는 일에 해당하는 부모리스트를 삭제하기만 해도 다에 해당하는 자식 엔티티가 delete되는 기능까지 포함되어있다.
FETCH
- Lazy인 경우에도 fetch join을 통해 즉시 불러올 수 있다
- Lazy를 사용한뒤에 필요할때 fetch join을 사용한다
- 옵션
EAGER : 즉시 로딩 (부모 조회 시 자식도 같이 조회)
LAZY : 지연 로딩 (자식은 필요할때 따로 조회)
JpaRepository 쿼리 사용방법
- 리턴타입 {접두어}{도입부}By{프로퍼티 표현식}(조건식)[(And|Or){프로퍼티 표현식}(조건식)](OrderBy{프로퍼티}Asc|Desc) (매개변수...)
접두어 : Find, Get, Query, Count, ...
도입부 : Distinct, First(N), Top(N)
프로퍼티 표현식 : Person.Address.ZipCode => find(Person)ByAddress_ZipCode(...)
조건식 : IgnoreCase, Between, LessThan, GreaterThan, Like, Contains, ...
정렬 조건 : OrderBy{프로퍼티}Asc|Desc
리턴 타입 : E, Optional<E>, List<E>, Page<E>, Slice<E>, Stream<E>
매개변수 : Pageable, Sort
Pageable
- 페이지네이션을 위한 인터페이스 PageRequest객체를 통해 페이지번호와 페이지 크기를 설정하여 데이터의 특정 페이지 조회를 요청할 수 있음
// 첫 페이지 (페이지 사이즈 = 2) Pageable firstPageWithTwoElements = PageRequest.of(0, 2); // 두번째 페이지 (페이지 사이즈 = 5) Pageable secondPageWithFiveElements = PageRequest.of(1, 5);
page, slice, list등으로 데이터를 받을 수 있음
Sorting
- sort객체를 사용하여 결과를 정렬 할 수 있음
- 정렬과 페이지네이션을 동시에 수행할때 PageRequest객체에 정렬 정보를 같이 전달할 수 있음.
Pageable sortedByName = PageRequest.of(0, 3, Sort.by("name")); Pageable sortedByPriceDesc = PageRequest.of(0, 3, Sort.by("price").descending()); Pageable sortedByPriceDescNameAsc = PageRequest.of(0, 5, Sort.by("price").descending().and(Sort.by("name")));
효율적으로 jpaRepository 사용하기
- Optional 제거하기
findByxxx메서드는 기본적으로 Optional을 반환하는데 비즈니스로직에서는 Optional처리 코드가 필요하게된다.
해결책 : defalut메서드를 사용하여 Optional처리코드를 내부적으로 해결할수있다.
public interface UserRepository extends JpaRepository<User, Long> { default User findUserById(Long id) { return findById(id).orElseThrow(() -> new DataNotFoundException("User not found with id: " + id)); } }
- 메서드명 간소화하기
쿼리 메서드는 지나치게 메서드명이 길어질 수 있음
해결책 : default를 사용하여 복잡한 쿼리메서드를 간결하게 가능
public interface ProductRepository extends JpaRepository<Product, Long> { // 기존의 긴 쿼리 메소드 List<Product> findAllByCategoryAndPriceGreaterThanEqualAndPriceLessThanEqualOrderByPriceAsc(String category, BigDecimal minPrice, BigDecimal maxPrice); // Default 메소드를 사용하여 간결한 메소드명 제공 default List<Product> findProductsByCategoryAndPriceRange(String category, BigDecimal minPrice, BigDecimal maxPrice) { return findAllByCategoryAndPriceGreaterThanEqualAndPriceLessThanEqualOrderByPriceAsc(category, minPrice, maxPrice); } }
- 비즈니스 로직 통합
여러 기본 메서드를 결합해 비즈니스 로직을 통합 할 수 있음
public interface UserRepository extends JpaRepository<User, Long> { default void updateUserContact(Long userId, String newContact) { findById(userId).ifPresent(user -> { user.setContact(newContact); save(user); }); } }
위코드는 findbyId와 save두개를 사용하였다.
페이지네이션
- JpaRepository에서 ListPagingAndSortingRepository를 제공한다
테이블 객체로 수동 쿼리 생성하기 (JPQL)
- 프로세스
1. PageRequest를 사용하여 페이징 정보를 담은 Pageable 객체를 생성.
2. Pageable 객체와 함께 JpaRepository의 메서드에 파라미터로 전달.
3. 메서드 호출 결과로 Page<T> 객체가 반환되며, 페이징 정보와 함께 데이터를 포함함.
4. 반환된 Page<T>의 페이징 정보를 사용하여 필요한 로직을 처리함.
요청: Pageable (org.springframework.data.domain.Pageable) – 페이징 정보를 제공하는 인터페이스.
PageRequest.of(int page, int size) : 0부터 시작하는 페이지 번호와 개수. 정렬이 지정되지 않음 PageRequest.of(int page, int size, Sort sort) : 페이지 번호와 개수, 정렬 관련 정보 PageRequest.of(int page int size, Sort sort, Direction direction, String ... props) : 0부터 시작하는 페이지 번호와 개수, 정렬의 방향과 정렬 기준 필드들 pageable.getTotalPages() : 총 페이지 수 pageable.getTotalElements() : 전체 개수 pageable.getNumber() : 현재 페이지 번호 pageable.getSize() : 페이지 당 데이터 개수 pageable.hasnext() : 다음 페이지 존재 여부 pageable.isFirst() : 시작페이지 여부 pageable.getContent(), PageRequest.get() : 실제 컨텐츠를 가지고 오는 메서드. getContext는 List<Entity> 반환, get()은 Stream<Entity> 반환
응답: Page<T> (org.springframework.data.domain.Page) – 페이징된 데이터와 전체 요소 수를 포함하는 반환 타입. - 페이지 반환 타입
Page<T>: 게시판 형태의 페이징에 사용되며, 전체 요소 수 (totalElements)를 포함.
Slice<T>: 더보기 형태의 페이징에 사용되며, 전체 요소 수를 포함하지 않고 limit+1 조회를 사용.
List<T>: 전체 목록보기 형태로 사용되며, 별도의 카운트 쿼리가 발생하지 않음. - 정렬
컬럼값으로 정렬하기 (Sort)
Sort sort1 = Sort.by("name").descending(); // 내림차순 Sort sort2 = Sort.by("password").ascending(); // 오름차순 Sort sortAll = sort1.and(sort2); // 2개이상 다중정렬도 가능하다 Pageable pageable = PageRequest.of(0, 10, sortAll); // pageable 생성시 추가
- 컬럼이 아닌 값으로 정렬하기
@Queryt 어노테이션 사용시 alias를 기준으로 정렬 할 수 있다
// 아래와 같이 AS user_password 로 Alias(AS) 를 걸어주면 @Query("SELECT u.user_name, u.password AS user_password FROM user u WHERE u.username = ?1") List<User> findByUsername(String username, Sort sort); // 이렇게 해당 user_password 를 기준으로 정렬할 수 있다. List<User> users = findByUsername("user", Sort.by("user_password"));
- sql함수를 사용해서 정렬하기
jpasort를 사용해서 쿼리 함수를 기준으로 정렬할 수 있음
// 아래와 같이 일반적인 쿼리에서 @Query("SELECT u FROM user u WHERE u.username = ?1") // 이건 없어도됨 List<User> findByUsername(String username, Sort sort); // 이렇게 쿼리함수 LENGTH() 조건을 걸어서 password 문자길이 기준으로 정렬할 수 있다. List<User> users = findByUsername("user", JpaSort.unsafe("LENGTH(password)"));
테이블 객체로 수동 쿼리 생성하기( JPQL)
- JPQL이란
TABLE이 아닌 ENTITY 기준으로 작성하는 쿼리
EntityManager또는 @Query 구현체를 통해 JPQL쿼리를 사용할 수 있음 - @Query 어노테이션 사용
쿼리를 작성할때는 테이블명이아닌 entity명으로 조회할 수 있음
변수 바인딩의 두가지 방법
1. ?변수 순번 사용
?매개변수 순번을 사용하여 매개변수와 매핑을 한다.public interface UserRepository extends JpaRepository<User, Long> { @Query("SELECT u, u.password AS customField FROM User u WHERE u.username = ?1") List<User> findByUsernameWithCustomField(String username, Sort sort); @Query("SELECT u FROM User u WHERE u.username = ?1") List<User> findByUsername(String username, Sort sort); }
2. :변수명 사용
public interface UserRepository extends JpaRepository<User, Long> { @Query("SELECT u, u.password AS customField FROM User u WHERE u.username = :username") List<User> findByUsernameWithCustomField(String username, Sort sort); @Query("SELECT u FROM User u WHERE u.username = :username") List<User> findByUsername(String username, Sort sort); }
:변수명을 사용하여 매핑한다
QUERY DSL
- ENTITY의 매핑 정보를 기반으로 쿼리 전용 클래스(Q클래스)를 생성하고, 이 클래스들을 사용해 객체 또는 함수 기반으로 쿼리를 사용할수있게 하는방법
Q 클래스 : ENTITY를 기반으로 자동으로 생성된 클래스로, 문자열 대신 객체를 사용해 쿼리를 구성 할 수 있음 - JPAQueryFactory : Q클래스를 사용해 객체 지향적으로 쿼리를 작성하고 실행해주는 기술
@PersistenceContext EntityManager em; public List<User> selectUserByUsernameAndPassword(String username, String password){ JPAQueryFactory jqf = new JPAQueryFactory(em); QUser user = QUser.user; List<Person> userList = jpf .selectFrom(user) .where(person.username.eq(username) .and(person.password.eq(password)) .fetch(); return userList; }
예시
JPAQueryFactory를 사용하기위해 추가해야할 코드
// configuration 패키지안에 추가 @Configuration public class JPAConfiguration { @PersistenceContext private EntityManager entityManager; @Bean public JPAQueryFactory jpaQueryFactory() { return new JPAQueryFactory(entityManager); } }
JPA Auditing
- Auditing을 사용하면 엔티티를 언제 생성, 마지막 수정했는지 자동으로 기록할 수 있음
- 적용방법
1. 메인 애플리케이션 위에 @EnableJpaAuditing 추가
2. 엔티티 클래스 위 @EntityListeners(AuditingEntityListener.class) 추가
Dynamic Insert/Update
- 엔티티에서 필요한 필드만을 포함하는 쿼리를 생성하여 성능을 최적화하는 기능
- DynamicInsert
null 값인 필드를 제외하고 inserty쿼리 생성
entity에 @DynamicInsert 어노테이션 추가 - DynamicUpdate
null 값인 필드를 제외하고 update쿼리 생성
entity에 @DynamicUpdate 어노테이션 추가 - insert/update 시 생성, 수정된 쿼리만 포함되므로 성능이 개선될 수 있음.
Docker강의
더보기
CI CD란?
- 코드의 지속적인 통합, 지속적인 서비스제공, 지속적인 배포
코드작성 : 개발자는 소스코드를 작성하고 저장소에 업로드
빌드 : 저장소에서 최신 소스코드를 가져와 빌드를 수행한다
테스트 : 빌드된 결과물을 대상으로 테스트를 수행한다
배포 : 테스트를 통과한 결과물을 배포한다. - 왜 필요한가?
과거의 개발방식과 달리 현재는 애자일 개발로 바뀌었다.
빠른기간동안 테스트 및 출시를 하게되는데
과거 개발방식대로 하면 빠르게 배포하는것이 불가능해진다
DOCKER를 통해 서버를 표준화하고 같은 환경에서 테스트 및 배포 테스트를 진행하고, 이 과정을 자동화한다.
DOCKER
- 왜 도커를 사용해야하는가
애플리케이션 개발과 배포가 편해진다
지속적인 통합 과정의 테스트에서 DOCKER를 사용한다.
여러 애플리케이션의 독립성과 확장성이 높아진다
DOCKER이 가상화에서 표준이다 거의 - docker이미지란?
container 런타임에 필요한 바이너리, 라이브러리 및 설정 값 등을 포함하고 변경되는 상태값을 보유하지 않고 변하지않음.
도커 이미지는 registry / hub 같은 공간에 저장되어있으며 공개된 공개된 공간이라고 할 수 있다.
pull받고 run을하거나, 도커이미지를 만들고, build를 수행하며 image를 push하거나 run 할 수 있다. - 명령어
docker pull : 도커 이미지 내려받기
docker [image] pull [options] name:tag
# docker [image] pull [options] name:[tag] # 최초에는 docker.io가 default registry로 설정됨. docker pull debian[:latest] docker pull library/debian:10 docker pull docker.io/library/debian:10 docker pull index/docker.io/library/debian:10 docker pull nginx:latest # private registry 나 클라우드 저장소의 이미지를 받는 경우 docker pull 192.168.0.101:5000/debian:10 # 현재는 실제로 동작하지 않음 docker pull gcr.io/google-samples/hello-app:1.0
docker image inspect : docker 이미지 구조 확인
>>docker image inspect nginx:latest
docker image history : dockerfile에 대한 정보 조회 가능
도커 컨테이너
- 도커 이미지 : 컨테이너에 대한 os, application, library 등등의 정보를 담고 있다
- 도커 컨테이너 : image를 실행한 상태 1개의 image로 부터 n개의 컨테이너를 생성할수 있는 1:n의 관계
- 컨테이너 상태
running(실행), paused(대기), stopped(정지) - 컨테이너 수동 생성
docker pull ubuntu:22.04 >> 우분투 22.04 이미지를 로컬로 다운로드 함 docker images >>실행결과 REPOSITORY TAG IMAGE ID CREATED SIZE debian latest c7f9867d6721 2 days ago 117MB ubuntu 22.04 97271d29cb79 2 weeks ago 77.9MB nginx latest 9527c0f683c3 6 weeks ago 188MB debian 10 69530eaa9e7e 3 months ago 115MB nginx 1.25.3-alpine 2b70e4aaac6b 11 months ago 42.6MB # docker create 은 실제 실행하지 않고 컨테이너 생성만 docker create –ti --name ubuntu2204test ubuntu:22.04 >> 우분투 22.04 이미지를 사용해 ubuntu2204test라는 이름의 컨테이너를 생성하되 실행되지않음 >> 실행결과 cb46d97ea8ff4f2e9867e8fdb0396c5ed12dafaadcbd05e30661104a0b117dbe docker ps –a >> 모든 컨테이너의 목록을출력함 >>실행결과 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cb46d97ea8ff ubuntu:22.04 "/bin/bash" 6 seconds ago Created ubuntu2204test a8035117baa6 nginx:1.25.3-alpine "/docker-entrypoint.…" 13 minutes ago Up 13 minutes 0.0.0.0:8001->80/tcp webserver01 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2ccc1b2a1144 ubuntu:22.04 "/bin/bash" 4 seconds ago Created ubuntu2204test docker start ubuntu2204test >> 도커 컨테이너를 실행함 >>실행결과 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cb46d97ea8ff ubuntu:22.04 "/bin/bash" 6 seconds ago Created ubuntu2204test a8035117baa6 nginx:1.25.3-alpine "/docker-entrypoint.…" 13 minutes ago Up 13 minutes 0.0.0.0:8001->80/tcp webserver01 user@localhost:~$ docker start ubuntu2204test ubuntu2204test user@localhost:~$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cb46d97ea8ff ubuntu:22.04 "/bin/bash" 2 minutes ago Up 13 seconds ubuntu2204test a8035117baa6 nginx:1.25.3-alpine "/docker-entrypoint.…" 16 minutes ago Up 16 minutes 0.0.0.0:8001->80/tcp webserver01 user@localhost:~$ docker attach ubuntu2204test root@cb46d97ea8ff:/# exit exit user@localhost:~$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cb46d97ea8ff ubuntu:22.04 "/bin/bash" 3 minutes ago Exited (0) 2 seconds ago ubuntu2204test a8035117baa6 nginx:1.25.3-alpine "/docker-entrypoint.…" 17 minutes ago Up 17 minutes 0.0.0.0:8001->80/tcp webserver01 >> 위 결과는 docker를 실행하지 않은 상태에서 status가 created를 확인하고 >> 실행한결과 up 13 seconds로 바뀐결과를 확인할수있고 >> attach 후 exit을 한뒤 상태를 확인한 결과이다. docker attach ubuntu2204test >>실행중인 ubuntu2204 컨테이너에 연결함 # docker run 은 create/start/attach 를 순차적으로 한 번에 실행하는 것과 같음 docker run -ti --name=ubuntu2204test2 ubuntu:22.04 /bin/bash root@57a1a1c759b6:/#
docker run의 옵션
-d : 백그라운드 모드
-p : 호스트와 컨테이너의 포트를 연결
-v : 호스트와 컨테이너의 디렉토리를 연결
-e : 컨테이너 내에서 사용할 환경변수 설정
-name : 컨테이너 이름 설정
-rm : 프로세스 종료 시 컨테이너 자동 삭제
-ti : -i와 -t 를 동시에 사용한것 - 명령어
# 컨테이너에서 실행 중인 프로세스 조회 docker top node-test UID PID PPID C STIME TTY TIME CMD root 2398 2378 0 08:37 ? 00:00:00 /sbin/tini -- node runapp.js root 2421 2398 0 08:37 ? 00:00:00 node runapp.js # 컨테이너에 매핑된 포트 조회 docker port node-test 8080/tcp -> 0.0.0.0:8080 # 컨테이너 리소스 통계 출력 (1회) docker stats node-test --no-stream CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS 14c475f7ac09 node-test 0.01% 9.035MiB / 15.45GiB 0.06% 1.5kB / 518B 0B / 0B 11 # 컨테이너 리소스 통계 출력 (스트림) docker stats node-test # 표준 출력(stdout), 표준에러(stderr) 출력 docker logs node-test # 로그를 계속 출력 docker logs –f node-test # 출력된 로그는 파일로 관리되기 때문에 HostOS 의 disk 를 사용 docker info | grep -i log # 컨테이너 내부 확인 docker inspect node-test [ { "Id": "2ccc1b2a114495e2d0b67f84e55c9c21e79c6bfff6355ae1fc2caa5225698bba", "Created": "2023-10-29T08:04:36.295616146Z", "Path": "/bin/bash", "Args": [], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 1814, "ExitCode": 0, "Error": "", "StartedAt": "2023-10-29T08:05:15.974255879Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:e4c58958181a5925816faa528ce959e487632f4cfd192f8132f71b32df2744b4", "ResolvConfPath": "/var/lib/docker/containers/2ccc1b2a114495e2d0b67f84e55c9c21e79c6bfff6355ae1fc2caa5225698bba/resolv.conf", "HostnamePath": "/var/lib/docker/containers/2ccc1b2a114495e2d0b67f84e55c9c21e79c6bfff6355ae1fc2caa5225698bba/hostname", # 터미널1, 도커 상태 확인 docker stats # 터미널2, 도커 프로세스 이벤트 확인 docker events # 터미널3, docker start docker stop node-test docker ps –a docker start node-test # docker pause node-test docker unpause node-test docker ps -a
- 도커 컨테이너 정리법
docker container prune : 실행중이 아닌 모든 컨테이너를 삭제
docker image prune : 태그가 붙지않은 모든 이미지 삭제
docker system prune : 사용하지 않는 도커 이미지, 컨테이너, 볼륨, 네트워크 등 모든 도커 리소스를 일괄적으로 삭제.
github actions를 활용한 ci/cd 파이프라인
- github action은 github에 내장된 ci/cd도구이다
- github의 ci
test를 통과한 코드만 dev브랜치와 main브랜치에 merge되도록 하여 오류를 방지함
dev브랜치에 merge된 경우 gradle test를 진행함
# action의 이름을 지정한다 name: 'CI' # Event Trigger 특정 액션 (Push, Pull_Request)등이 명시한 Branch에서 일어나면 동작을 수행한다. on: push: # 배열로 여러 브랜치를 넣을 수 있다. 현재는 develop과 feature/의 하위 모든 브랜치 branches: [ develop, feature/* ] # github pull request 생성시 pull_request: branches: - develop # -를 쓴 여러 줄로 여러 브랜치를 명시하는 것도 가능 # 실제 어떤 작업을 실행할지에 대한 명시 jobs: #ci는 그냥 이름 ci: # 스크립트 실행 환경 (OS) >> ubuntu-latest # 배열로 선언시 개수 만큼 반복해서 실행한다. ( 예제 : 1번 실행) runs-on: [ ubuntu-latest ] # 실제 실행 스크립트 steps: # uses는 github actions에서 제공하는 플러그인을 실행.(git checkout 실행) # 코드를 서버에서 가져오는 단계 - name: checkout uses: actions/checkout@v4 # with은 plugin 파라미터 입니다. (java 11버전 셋업) # 테스트할 자바 버전 설정 - name: java setup uses: actions/setup-java@v2 with: distribution: 'adopt' # See 'Supported distributions' for available options java-version: '17' # run은 사용자 지정 스크립트 실행 - name: run unittest run: | ./gradlew clean test
- github의 cd
배포를 자동화하는 작업을 기술해서 빠르고 간편하게 배포
#이름 정의 name: 'CD' # event trigger main 브랜치에 push시 on: push: branches: [ main ] #아래의 내용을 수행한다 jobs: #cd라는 이름으로 정의 cd: #스크립트 실행환경ubuntu-latest 실행 runs-on: [ ubuntu-latest ] steps: # git checkout 실행 - name: checkout uses: actions/checkout@v4 #자바 버전 정의 - name: java setup uses: actions/setup-java@v3 with: distribution: 'adopt' # See 'Supported distributions' for available options java-version: '17' #테스트 진행 - name: run unittest run: | ./gradlew clean test # 배포 - name: deploy to heroku uses: akhileshns/heroku-deploy@v3.12.12 with: heroku_api_key: ${{secrets.HEROKU_API_KEY}} heroku_app_name: "sampleapp-github-actions" #Must be unique in Heroku heroku_email: "nbcdocker@proton.me"
- github actions의 실행순서
- workflow
최상위 개념으로 여러개의 job으로 구성되고 event에 의해 트리거 될 수 있는 자동화된 프로세스
workflow 파일의 yaml으로 작성되고, github repository의 .github/workflows 폴더 아래 저장됨 - event
github repository에서 발생하는 push, pull request open, issue open, 특정시간대 반복 등의 특정한규칙
위가 발생한 경우에 workflow를 실행함 - runner
github action runner app이 설치된 vm
하나의 workflow가 실행될 instance로 각각의 job들은 개별의 runner에서 실행 - job
하나의 runner에서 실행될 여러 step들의 모음 - step
실행 가능한 하나의 shell script 또는 action
'TIL' 카테고리의 다른 글
20241001 본캠프 54일차 TIL (1) | 2024.10.01 |
---|---|
20240930 본캠프 53일차 TIL (0) | 2024.09.30 |
20240921 본캠프 51일차 TIL (0) | 2024.09.26 |
20240925 본캠프 50일차 TIL (0) | 2024.09.25 |
20240919 본캠프 46일차 TIL (0) | 2024.09.19 |