-
Notifications
You must be signed in to change notification settings - Fork 36
[volume-10] Collect, Stack, Zip #243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: adminhelper
Are you sure you want to change the base?
Changes from 7 commits
d9ae7ad
c5754ff
deda1e2
617746d
e882552
d5a2599
febeab0
072f563
d824c55
1855942
3028233
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,13 @@ | ||||||||||
| name: PR Agent | ||||||||||
| on: | ||||||||||
| pull_request: | ||||||||||
| types: [opened, synchronize] | ||||||||||
| jobs: | ||||||||||
| pr_agent_job: | ||||||||||
| runs-on: ubuntu-latest | ||||||||||
| steps: | ||||||||||
| - name: PR Agent action step | ||||||||||
| uses: Codium-ai/pr-agent@main | ||||||||||
| env: | ||||||||||
| OPENAI_KEY: ${{ secrets.OPENAI_KEY }} | ||||||||||
| GITHUB_TOKEN: ${{ secrets.G_TOKEN }} | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ๐งฉ Analysis chain๐ Script executed: # ์ํฌํ๋ก์ฐ ํ์ผ ์ ์ฒด ๋ด์ฉ ํ์ธ
cat -n .github/workflows/main.ymlRepository: Loopers-dev-lab/loopers-spring-java-template Length of output: 487 ๐ Script executed: # ๋ฆฌํฌ์งํ ๋ฆฌ์์ G_TOKEN ์ฐธ์กฐ ๊ฒ์
rg "G_TOKEN" --type yaml --type mdRepository: Loopers-dev-lab/loopers-spring-java-template Length of output: 70 ๐ Script executed: # ์ํฌํ๋ก์ฐ ํ์ผ์์ GITHUB_TOKEN ์ฌ์ฉ ํจํด ํ์ธ
rg "GITHUB_TOKEN|secrets\." .github/workflows/ -A 2 -B 2Repository: Loopers-dev-lab/loopers-spring-java-template Length of output: 341 ๐ Web query:
๐ก Result: Summary โ GITHUB_TOKEN for CodiumโAI / pr-agent (GitHub Action)
Sources
๐ Script executed: # ์ํฌํ๋ก์ฐ ํ์ผ์ ์ ์ฒด ๊ตฌ์กฐ ํ์ธ (์จ๊ฒจ์ง ๋ถ๋ถ์ด ์๋์ง ํ์ธ)
wc -l .github/workflows/main.ymlRepository: Loopers-dev-lab/loopers-spring-java-template Length of output: 117
Codium-ai/pr-agent๋ ์๋์ผ๋ก ์ ๊ณต๋๋ ๊ถ์ฅ ์์ env:
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
- GITHUB_TOKEN: ${{ secrets.G_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}๐ Committable suggestion
Suggested change
๐ค Prompt for AI Agents |
||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| dependencies { | ||
| // add-ons | ||
| implementation(project(":modules:jpa")) | ||
| implementation(project(":modules:redis")) | ||
| implementation(project(":supports:jackson")) | ||
| implementation(project(":supports:logging")) | ||
| implementation(project(":supports:monitoring")) | ||
|
|
||
| // batch | ||
| implementation("org.springframework.boot:spring-boot-starter-batch") | ||
| testImplementation("org.springframework.batch:spring-batch-test") | ||
|
|
||
| // querydsl | ||
| annotationProcessor("com.querydsl:querydsl-apt::jakarta") | ||
| annotationProcessor("jakarta.persistence:jakarta.persistence-api") | ||
| annotationProcessor("jakarta.annotation:jakarta.annotation-api") | ||
|
|
||
| // test-fixtures | ||
| testImplementation(testFixtures(project(":modules:jpa"))) | ||
| testImplementation(testFixtures(project(":modules:redis"))) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package com.loopers; | ||
|
|
||
| import jakarta.annotation.PostConstruct; | ||
| import org.springframework.boot.SpringApplication; | ||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
| import org.springframework.boot.context.properties.ConfigurationPropertiesScan; | ||
|
|
||
| import java.util.TimeZone; | ||
|
|
||
| @ConfigurationPropertiesScan | ||
| @SpringBootApplication | ||
| public class CommerceBatchApplication { | ||
|
|
||
| @PostConstruct | ||
| public void started() { | ||
| // set timezone | ||
| TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul")); | ||
| } | ||
|
|
||
| public static void main(String[] args) { | ||
| int exitCode = SpringApplication.exit(SpringApplication.run(CommerceBatchApplication.class, args)); | ||
| System.exit(exitCode); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package com.loopers.batch.job.demo; | ||
|
|
||
| import com.loopers.batch.job.demo.step.DemoTasklet; | ||
| import com.loopers.batch.listener.JobListener; | ||
| import com.loopers.batch.listener.StepMonitorListener; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.batch.core.Job; | ||
| import org.springframework.batch.core.Step; | ||
| import org.springframework.batch.core.configuration.annotation.JobScope; | ||
| import org.springframework.batch.core.job.builder.JobBuilder; | ||
| import org.springframework.batch.core.launch.support.RunIdIncrementer; | ||
| import org.springframework.batch.core.repository.JobRepository; | ||
| import org.springframework.batch.core.step.builder.StepBuilder; | ||
| import org.springframework.batch.support.transaction.ResourcelessTransactionManager; | ||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
| import org.springframework.context.annotation.Bean; | ||
| import org.springframework.context.annotation.Configuration; | ||
|
|
||
| @ConditionalOnProperty(name = "spring.batch.job.name", havingValue = DemoJobConfig.JOB_NAME) | ||
| @RequiredArgsConstructor | ||
| @Configuration | ||
| public class DemoJobConfig { | ||
| public static final String JOB_NAME = "demoJob"; | ||
| private static final String STEP_DEMO_SIMPLE_TASK_NAME = "demoSimpleTask"; | ||
|
|
||
| private final JobRepository jobRepository; | ||
| private final JobListener jobListener; | ||
| private final StepMonitorListener stepMonitorListener; | ||
| private final DemoTasklet demoTasklet; | ||
|
|
||
| @Bean(JOB_NAME) | ||
| public Job demoJob() { | ||
| return new JobBuilder(JOB_NAME, jobRepository) | ||
| .incrementer(new RunIdIncrementer()) | ||
| .start(categorySyncStep()) | ||
| .listener(jobListener) | ||
| .build(); | ||
| } | ||
|
|
||
| @JobScope | ||
| @Bean(STEP_DEMO_SIMPLE_TASK_NAME) | ||
| public Step categorySyncStep() { | ||
| return new StepBuilder(STEP_DEMO_SIMPLE_TASK_NAME, jobRepository) | ||
| .tasklet(demoTasklet, new ResourcelessTransactionManager()) | ||
| .listener(stepMonitorListener) | ||
| .build(); | ||
| } | ||
|
Comment on lines
+40
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ๐ ๏ธ Refactor suggestion | ๐ Major ๋ฉ์๋๋ช ๊ณผ ์คํ ๋ช ์ ๋ถ์ผ์น๋ฅผ ์์ ํ์ธ์. ๋ฉ์๋๋ช
๐ ์ ์๋ ์์ @JobScope
@Bean(STEP_DEMO_SIMPLE_TASK_NAME)
- public Step categorySyncStep() {
+ public Step demoSimpleTaskStep() {
return new StepBuilder(STEP_DEMO_SIMPLE_TASK_NAME, jobRepository)
.tasklet(demoTasklet, new ResourcelessTransactionManager())
.listener(stepMonitorListener)
.build();
}๊ทธ๋ฆฌ๊ณ Job ๋น์์๋ ๋ฉ์๋๋ช ์ ์ ๋ฐ์ดํธํ์ธ์: @Bean(JOB_NAME)
public Job demoJob() {
return new JobBuilder(JOB_NAME, jobRepository)
.incrementer(new RunIdIncrementer())
- .start(categorySyncStep())
+ .start(demoSimpleTaskStep())
.listener(jobListener)
.build();
}
๐ค Prompt for AI Agents |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| package com.loopers.batch.job.demo.step; | ||
|
|
||
| import com.loopers.batch.job.demo.DemoJobConfig; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.batch.core.StepContribution; | ||
| import org.springframework.batch.core.configuration.annotation.StepScope; | ||
| import org.springframework.batch.core.scope.context.ChunkContext; | ||
| import org.springframework.batch.core.step.tasklet.Tasklet; | ||
| import org.springframework.batch.repeat.RepeatStatus; | ||
| import org.springframework.beans.factory.annotation.Value; | ||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
| import org.springframework.stereotype.Component; | ||
|
|
||
| @StepScope | ||
| @ConditionalOnProperty(name = "spring.batch.job.name", havingValue = DemoJobConfig.JOB_NAME) | ||
| @RequiredArgsConstructor | ||
| @Component | ||
| public class DemoTasklet implements Tasklet { | ||
| @Value("#{jobParameters['requestDate']}") | ||
| private String requestDate; | ||
|
|
||
| @Override | ||
| public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { | ||
| if (requestDate == null) { | ||
| throw new RuntimeException("requestDate is null"); | ||
| } | ||
| System.out.println("Demo Tasklet ์คํ (์คํ ์ผ์ : " + requestDate + ")"); | ||
| Thread.sleep(1000); | ||
| System.out.println("Demo Tasklet ์์ ์๋ฃ"); | ||
| return RepeatStatus.FINISHED; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package com.loopers.batch.listener; | ||
|
|
||
| import lombok.RequiredArgsConstructor; | ||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.springframework.batch.core.annotation.AfterChunk; | ||
| import org.springframework.batch.core.scope.context.ChunkContext; | ||
| import org.springframework.stereotype.Component; | ||
|
|
||
| @Slf4j | ||
| @RequiredArgsConstructor | ||
| @Component | ||
| public class ChunkListener { | ||
|
|
||
| @AfterChunk | ||
| void afterChunk(ChunkContext chunkContext) { | ||
| log.info( | ||
| "์ฒญํฌ ์ข ๋ฃ: readCount: ${chunkContext.stepContext.stepExecution.readCount}, " + | ||
| "writeCount: ${chunkContext.stepContext.stepExecution.writeCount}" | ||
| ); | ||
|
Comment on lines
+16
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Java๋ ๋ฌธ์์ด ๋ณด๊ฐ์ ์ง์ํ์ง ์์ต๋๋ค. ๋ก๊ทธ ๋ฉ์์ง์์ ๐ ์ฌ๋ฐ๋ฅธ ๋ก๊น ๋ฐฉ์SLF4J์ ํ๋ผ๋ฏธํฐํ๋ ๋ก๊น ์ ์ฌ์ฉํ์ธ์: log.info(
- "์ฒญํฌ ์ข
๋ฃ: readCount: ${chunkContext.stepContext.stepExecution.readCount}, " +
- "writeCount: ${chunkContext.stepContext.stepExecution.writeCount}"
+ "์ฒญํฌ ์ข
๋ฃ: readCount: {}, writeCount: {}",
+ chunkContext.getStepContext().getStepExecution().getReadCount(),
+ chunkContext.getStepContext().getStepExecution().getWriteCount()
);๐ค Prompt for AI Agents |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,53 @@ | ||||||||||||||||||||||
| package com.loopers.batch.listener; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| import lombok.RequiredArgsConstructor; | ||||||||||||||||||||||
| import lombok.extern.slf4j.Slf4j; | ||||||||||||||||||||||
| import org.springframework.batch.core.JobExecution; | ||||||||||||||||||||||
| import org.springframework.batch.core.annotation.AfterJob; | ||||||||||||||||||||||
| import org.springframework.batch.core.annotation.BeforeJob; | ||||||||||||||||||||||
| import org.springframework.stereotype.Component; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| import java.time.Duration; | ||||||||||||||||||||||
| import java.time.Instant; | ||||||||||||||||||||||
| import java.time.ZoneId; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @Slf4j | ||||||||||||||||||||||
| @RequiredArgsConstructor | ||||||||||||||||||||||
| @Component | ||||||||||||||||||||||
| public class JobListener { | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @BeforeJob | ||||||||||||||||||||||
| void beforeJob(JobExecution jobExecution) { | ||||||||||||||||||||||
| log.info("Job '${jobExecution.jobInstance.jobName}' ์์"); | ||||||||||||||||||||||
| jobExecution.getExecutionContext().putLong("startTime", System.currentTimeMillis()); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+19
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Java๋ ๋ฌธ์์ด ๋ณด๊ฐ์ ์ง์ํ์ง ์์ต๋๋ค. Line 21์ ๋ก๊ทธ ๋ฉ์์ง์์ ๐ ์ฌ๋ฐ๋ฅธ ๋ก๊น ๋ฐฉ์SLF4J์ ํ๋ผ๋ฏธํฐํ๋ ๋ก๊น ์ ์ฌ์ฉํ์ธ์: - log.info("Job '${jobExecution.jobInstance.jobName}' ์์");
+ log.info("Job '{}' ์์", jobExecution.getJobInstance().getJobName());๐ Committable suggestion
Suggested change
๐ค Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @AfterJob | ||||||||||||||||||||||
| void afterJob(JobExecution jobExecution) { | ||||||||||||||||||||||
| var startTime = jobExecution.getExecutionContext().getLong("startTime"); | ||||||||||||||||||||||
| var endTime = System.currentTimeMillis(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| var startDateTime = Instant.ofEpochMilli(startTime) | ||||||||||||||||||||||
| .atZone(ZoneId.systemDefault()) | ||||||||||||||||||||||
| .toLocalDateTime(); | ||||||||||||||||||||||
| var endDateTime = Instant.ofEpochMilli(endTime) | ||||||||||||||||||||||
| .atZone(ZoneId.systemDefault()) | ||||||||||||||||||||||
| .toLocalDateTime(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| var totalTime = endTime - startTime; | ||||||||||||||||||||||
| var duration = Duration.ofMillis(totalTime); | ||||||||||||||||||||||
| var hours = duration.toHours(); | ||||||||||||||||||||||
| var minutes = duration.toMinutes() % 60; | ||||||||||||||||||||||
| var seconds = duration.getSeconds() % 60; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| var message = String.format( | ||||||||||||||||||||||
| """ | ||||||||||||||||||||||
| *Start Time:* %s | ||||||||||||||||||||||
| *End Time:* %s | ||||||||||||||||||||||
| *Total Time:* %d์๊ฐ %d๋ถ %d์ด | ||||||||||||||||||||||
| """, startDateTime, endDateTime, hours, minutes, seconds | ||||||||||||||||||||||
| ).trim(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| log.info(message); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
์ก์ ๋ฒ์ ์ ํน์ ์ปค๋ฐ SHA๋ก ๊ณ ์ ํ์ธ์.
@main๋ธ๋์น๋ฅผ ์ฌ์ฉํ๋ฉด ํญ์ ์ต์ ์ฝ๋๊ฐ ์คํ๋์ด ๊ณต๊ธ๋ง ๋ณด์ ์ํ์ด ๋ฐ์ํ ์ ์์ต๋๋ค. GitHub Actions ๋ณด์ ๋ชจ๋ฒ ์ฌ๋ก์ ๋ฐ๋ผ third-party ์ก์ ์ ํน์ ์ปค๋ฐ SHA๋ก ๊ณ ์ ํด์ผ ํฉ๋๋ค.๐ ๊ถ์ฅ ์์ ์ฌํญ
์ต์ ๋ฆด๋ฆฌ์ค์ ์ปค๋ฐ SHA๋ฅผ ํ์ธํ๋ ค๋ฉด ๋ค์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ์ธ์:
๐ค Prompt for AI Agents